2017-06-02 11 views
0

私のサーバー上のセキュリティ実装に関する質問があります。 、資格情報のセキュリティを持つスプリングトークンセキュリティ(springboot)

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 




    @Override 
    protected void configure(HttpSecurity http) throws Exception { 


     http.antMatcher("/*").authorizeRequests().anyRequest().hasRole("ADMIN") 
     .and().formLogin().loginPage("/login.jsp") 
     .failureUrl("/login.jsp?error=1").loginProcessingUrl("/login") 
     .permitAll().and().logout() 
     .logoutSuccessUrl("/login.jsp"); 

    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    // Create a default account 
    auth.inMemoryAuthentication() 
     .withUser("admin") 
     .password("admin") 
     .roles("ADMIN"); 
    } 

すべてのウェブサイトのURLは、* /である:私は1つの管理者の入力がデータを必要に応じてその上にウェブサイト、などのコントロールパネルを持っているSpringBootアプリケーションを作っていますし、私はこのようなその部分の罰金を確保するために管理していますそれはうまく動作します。私がする必要があるのは、モバイルアプリからデータを取得することです。安全である必要があります。アプリで使用するURLは/ rest/**です。私は、Webサイトにその管理者によって作成された電子メール(ユーザー名)とパスワードを格納するStudentクラスを持っています。私が読んだ限り、私はトークンの実装が必要です。

トークン認証はどのように実装できますか?

答えて

1

モバイルアプリケーションのトークンベース認証を実装するには、SpringブートとSpringセキュリティが必要です。

最後にあなたのセキュリティコンフィグ

//Leave whatever you had here 
@Override 
public void configure(HttpSecurity http) throws Exception { 
    http.addFilterBefore(new TokenAuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class); 

    String contentPathDir = String.format("/%s/**", contentPath); 

    http.csrf().disable() 
      .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
      .and().authorizeRequests() 
      .antMatchers("/authorization/**", "/public/**", "/management/**", "/health/**", contentPathDir).permitAll() 
      .antMatchers("/**").authenticated(); 
} 




//Add these two below. 
@Override 
public void configure(AuthenticationManagerBuilder auth) { 
    auth.authenticationProvider(apiKeyAuthenticationProvider()); 
} 

@Bean 
public TokenAuthenticationProvider apiKeyAuthenticationProvider() { 
    return new TokenAuthenticationProvider(apiKey); 
} 
にこれらを登録し、セッションの資格ホルダーに

public class SessionCredentials { 

    String apiKey; 
    String accessToken; 

    public SessionCredentials(String apiKey, String accessToken) { 
     this.apiKey = apiKey; 
     this.accessToken = accessToken; 
    } 

    public String getApiKey() { 
     return apiKey; 
    } 

    public String getAccessToken() { 
     return accessToken; 
    } 
} 

を作成TokenAuthenticationFilter

public class TokenAuthenticationFilter extends GenericFilterBean { 

    private AuthenticationManager authenticationManager; 

    public TokenAuthenticationFilter(AuthenticationManager authenticationManager) { 
     this.authenticationManager = authenticationManager; 
    } 

    @Override 
    public void doFilter(ServletRequest request, 
              ServletResponse response, 
              FilterChain chain) throws IOException, ServletException { 

     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 

     String apiKey = httpRequest.getHeader("API-Key"); 
     String token = httpRequest.getHeader("Access-Token"); 

     try { 
      if (!StringUtils.isEmpty(apiKey)) { 
       processTokenAuthentication(apiKey); 
      } 
      chain.doFilter(request, response); 
     } catch (InternalAuthenticationServiceException internalAuthenticationServiceException) 
     { 
      SecurityContextHolder.clearContext(); 
      logger.error("Internal authentication service exception", internalAuthenticationServiceException); 
      httpResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
     } 
      catch(AuthenticationException authenticationException) 
     { 
      SecurityContextHolder.clearContext(); 
      httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage()); 
     } 
    } 

    private void processTokenAuthentication(String apiKey) { 
     SessionCredentials authCredentials = new SessionCredentials(apiKey); 
     Authentication requestAuthentication = new PreAuthenticatedAuthenticationToken(authCredentials, authCredentials); 
     Authentication resultOfAuthentication = tryToAuthenticate(requestAuthentication); 
     SecurityContextHolder.getContext().setAuthentication(resultOfAuthentication); 
    } 

    private Authentication tryToAuthenticate(Authentication requestAuthentication) { 
     Authentication responseAuthentication = authenticationManager.authenticate(requestAuthentication); 
     if (responseAuthentication == null || !responseAuthentication.isAuthenticated()) { 
      throw new InternalAuthenticationServiceException("Unable to authenticate Domain User for provided credentials"); 
     } 
     return responseAuthentication; 
    } 
} 

public class TokenAuthenticationProvider implements AuthenticationProvider { 

    private String apiKey; 

    public TokenAuthenticationProvider(String apiKey) { 
     this.apiKey = apiKey; 
    } 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
     SessionCredentials credentials = (SessionCredentials) authentication.getCredentials(); 
     if (credentials != null && credentials.apiKey.equals(this.apiKey)) { 

      //Also evaluate the token here 

      Authentication newAuthentication = new PreAuthenticatedAuthenticationToken(apiKey, credentials); 
      newAuthentication.setAuthenticated(true); 
      return newAuthentication; 
     } 
     throw new BadCredentialsException("Bad credentials given."); 
    } 

    @Override 
    public boolean supports(Class<?> aClass) { 
     return aClass.equals(PreAuthenticatedAuthenticationToken.class); 
    } 
} 

を作成します。

+0

https://github.com/appsquickly/movies-kotlin-spring-data-neo4j-4(非常に推奨される)JVM言語Kotlinを使用して、ここにトークンベースの認証とテストケースを持つサンプルアプリケーションがあります。 –

関連する問題