2017-04-10 13 views
-1

リクエストパラメータとしてJWTを受け入れ、認証時に新しいJWTを返すAPIを実装しています。Spring SecurityのUsernamePasswordAuthenticationをバイパスする方法

@RequestMapping(value = "/authenticate/token", method = RequestMethod.POST, 
    consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
    produces = MediaType.APPLICATION_JSON_VALUE) 
@Timed 
public ResponseEntity authenticate(@RequestParam("login_token") final String token, HttpServletResponse response) { 
    LOG.debug("Request to login with token : {}", token); 
    try { 
     String jwt = authService.loginByToken(token); 
     response.addHeader(JWTConfigurer.AUTHORIZATION_HEADER, "Bearer " + jwt); 
     return ResponseEntity.ok(new IdentityToken(jwt)); 
    } catch (AuthenticationException ae) { 
     LOG.trace("Authentication exception trace: {}", ae); 
     return new ResponseEntity<>(Collections.singletonMap("AuthenticationException", 
      ae.getLocalizedMessage()), HttpStatus.UNAUTHORIZED); 
    } 
} 

マイloginByToken実装はこの時点で

@Override public String loginByToken(String token) { 
    if (!tokenProvider.validateToken(token)) { 
     throw new BadCredentialsException("Token is invalid."); 
    } 
    SecureToken secureToken = tokenProvider.parseJwtToken(token); 
    User user = userRepository.findByEmail(secureToken.getEmail()); 

    // TODO: Check Account Status is valid, User status is valid 

    Calendar c = Calendar.getInstance(); 
    c.setTime(new Date()); 
    c.add(Calendar.DATE, Constants.PASSWORD_EXPIRY_DAYS); 

    if (user.getPasswordExpiryDt() != null 
     && user.getPasswordExpiryDt().after(c.getTime())) { 
     throw new BadCredentialsException("Password changed"); 
    } 

    // TODO: Find how to create authentication object and return ID token. 
    // return tokenProvider.createToken(authentication, false); 
    return token; 
} 

以下のように見える、私は私が作成しcreateToken関数に渡すことができるすべてのユーザーの詳細情報が含まれている認証オブジェクトを作成するかどうかはわかりませんアイデンティティトークン。

ここに私のプロジェクトは、この投稿に記載されている変更なしで - https://github.com/santoshkt/ngx-pipes-testです。

私は匿名認証、PreAuthenticatedなどについて読んだことがありますが、この場合の対処方法は不明です。これを行うにはどのような指針に感謝します。

答えて

1

便利願っていたサンプルhere

を見つけることができます。

:あなたは、おそらくそれはあなたのリクエストパラメータとあなたのトークンからユーザー/認証オブジェクトを取得し、認証プロバイダからトークンを取得し、フィルタを有するように、あなたの春のセキュリティ設定を変更したいあなたのケースで

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .antMatcher("/authenticate/token") 
     .authorizeRequests() 
      .anyRequest().authenticated() 
      .and() 
     // This is a filter bean you'll have to write 
     .addFilterBefore(filter(), RequestHeaderAuthenticationFilter.class) 
     // This is your token verifier/decoder 
     .authenticationProvider(authenticationProvider()) 
     .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); 
    } 

AbstractPreAuthenticatedProcessingFilterから拡張してlogin_tokenパラメータを返すことができます。ここでは、getPreAuthenticatedPrincipal()getPreAuthenticatedCredentials()という2つのメソッドを実装する必要があります。

@Override 
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
    // You could already decode your token here to return your username 
    return request.getParameter("login_token"); 
} 

@Override 
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
    return request.getParameter("login_token"); 
} 

あなたの認証プロバイダは、タイプPreAuthenticatedAuthenticationProviderであるべきであり、ここであなたがAuthenticationUserDetailsServiceを設定することができます。

@Bean 
public AuthenticationProvider authenticationProvider() { 
    PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); 
    // service is a bean of type AuthenticationUserDetailsService 
    // You could autowire this in your security configuration class 
    provider.setPreAuthenticatedUserDetailsService(service); 
    return provider; 
} 

今、あなたのトークンに基づいてUserDetailsオブジェクトを取得するために、独自のAuthenticationUserDetailsServiceを作成することができます。

@Service 
public class TokenAuthenticationUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { 

    @Override 
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken authentication) throws UsernameNotFoundException { 
     // In this case the authentication.getCredentials() will contain your token and you can return a UserDetails object 
     return new User(/** ... */); 
    } 
} 
0

あなたが最良のアプローチは、あなたがSpring Security Custom Entry Point を所有して作成することであるJWTトークン要求のためのHTMLページを提供したいので、それは認証を管理するための別のシステムの場合は、たとえば

探しhereを与える可能性と他のシステムを「信頼する」権限を管理してから、自分の権限を管理するだけです。この場合、hereのようにPreAuthentication Scenarioを使用できます。私はそれはあなたが春のセキュリティを使用したい場合、あなたはおそらく(事前)の認証を処理するために、Spring MVCのエンドポイントを使用しないでください

関連する問題