2016-05-13 16 views
2

私は、スプリングのセキュリティ(SS)を使用して、トークンベースの認証を実装するための多くの異なる方法を探していました。&私は本当にOauthルートでいっぱいに行きたいと思っていないので、何かをやろうとしていて、かなりシンプルにしています。APIのスプリングセキュリティとトークン認証

私が望むのは、SSの組み込みのメカニズムにユーザー名/パスワードを渡し、成功した場合に、ユーザーに渡すトークンを生成することです。その後、ユーザーはカスタムヘッダー内のトークンを使用してすべての将来の要求を行います。トークンは時間の経過とともに期限切れになります。私はこれがOauthがやっていることのようなものだと認識していますが、それを使用したくないです。

私は何か仕事をしています。私はユーザー名/パスワードでログインし、トークンを取り戻すことができます。私はその後、トークンを使ってリクエストを成功させることができます。権限がないと動かない。ここで私は...やってんだよ

    単に単にそのちょうど応答 HttpServletResponse.SC_UNAUTHORIZEDHttpServletResponse.SC_OKとトークン
  • カスタム認証エントリポイントを返しHttpServletResponse.SC_UNAUTHORIZED
  • カスタム成功ハンドラを返し
  • カスタム認証失敗ハンドラ

今、私はカスタムのUserDetailsとUserDetailsS​​erviceも持っています。

public class MyUserDetails implements UserDetails { 

    private User user; // this is my own User object 
    private List<GrantedAuthority> authorities; 

    public MyUserDetails(User user, List<GrantedAuthority> authorities) { 
     this.user = user; 
     this.authorities = authorities; 
    } 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     return authorities; 
    } 

    @Override 
    public String getPassword() { 
     return user.getPassword(); 
    } 

    @Override 
    public String getUsername() { 
     return user.getUsername(); 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return true; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    public void setAuthorities(List<GrantedAuthority> authorities) { 
     this.authorities = authorities; 
    } 
} 

@Service 
public class MyUserDetailsService implements UserDetailsService { 

    private final UserService userService; 

    @Autowired 
    public MyUserDetailsService(UserService userService) { 
     this.userService = userService; 
    } 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     User user = userService.findByUsername(username); 
     if (user == null) { 
      throw new UsernameNotFoundException(username); 
     } 

     List<GrantedAuthority> authorities = new ArrayList<>(); 
     // for now, just add something 
     authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 

     return new MyUserDetails(user, authorities); 
    } 
} 
トークンをヘッダーに見て、私はAuthTokenFilterを作成し、すべてが順調である春を告げるために

...

public class AuthTokenFilter extends UsernamePasswordAuthenticationFilter { 

    @Autowired 
    private MyUserDetailsService userDetailsService; 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     String authToken = httpRequest.getHeader("X-TOKEN-AUTH"); 
     String username = null; 
     if (authToken != null) { 
      username = Jwts.parser() 
        .setSigningKey("1234") 
        .parseClaimsJws(authToken) 
        .getBody() 
        .getSubject(); 


     } 

     if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { 
      UserDetails userDetails = userDetailsService.loadUserByUsername(username); 
      // TODO: validate token 
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); 
      authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 

     } 

     chain.doFilter(request, response); 

    } 
} 

そして、これは私は、Webのセキュリティを設定した方法です。

@Configuration 
@EnableWebSecurity 
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private MyUserDetailsService userDetailsService; 

    @Autowired 
    private RestAuthEntryPoint authenticationEntryPoint; 

    @Autowired 
    private AuthSuccessHandler authSuccessHandler; 

    @Autowired 
    private AuthFailureHandler authFailureHandler; 


    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Bean 
    @Override 
    public UserDetailsService userDetailsServiceBean() throws Exception { 
     return super.userDetailsServiceBean(); 
    } 

    @Bean 
    public AuthenticationProvider authenticationProvider() { 
     DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); 
     authenticationProvider.setUserDetailsService(userDetailsService); 
     authenticationProvider.setPasswordEncoder(new ShaPasswordEncoder()); 

     return authenticationProvider; 
    } 

    @Bean 
    public AuthTokenFilter authenticationTokenFilterBean() throws Exception { 
     AuthTokenFilter authenticationTokenFilter = new AuthTokenFilter(); 
     authenticationTokenFilter.setAuthenticationManager(authenticationManagerBean()); 
     return authenticationTokenFilter; 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(authenticationProvider()); 
    } 

    @Override 
    protected AuthenticationManager authenticationManager() throws Exception { 
     return super.authenticationManager(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.csrf().disable() 
       .authorizeRequests() 
       .antMatchers("/login").permitAll() 
       .anyRequest().authenticated() 
       .and() 
       .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
       .and() 
       .authenticationProvider(authenticationProvider()) 
       .exceptionHandling() 
       .authenticationEntryPoint(authenticationEntryPoint) 
       .and() 
       .formLogin() 
       .permitAll() 
       .loginProcessingUrl("/login") 
       .usernameParameter("username") 
       .passwordParameter("password") 
       .successHandler(authSuccessHandler) 
       .failureHandler(authFailureHandler) 
       .and() 
       .logout() 
       .permitAll() 
       .and() 
       .sessionManagement() 
       .maximumSessions(1); 

     http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); 

     http.authorizeRequests().anyRequest().authenticated(); 
    } 


} 

すべてが動作するようですが、SSはアクセスを制限していません。トークンがあれば、SSはすべてのものを通過させます。

答えて

3

まあ、多くの裁判の後、それは私がもっと早くこれに実行されなかったことに驚いの私のSpringSecurityConfig

@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)

種類に以下を追加するのと同じくらい簡単でしたエラー。これが若干新しいか何かなのかどうかは分かりません。

関連する問題