web-dev-qa-db-ja.com

応答としてのSpring5LDAP認証とJWTトークン

こんにちは私は、ユーザー/パスがLDAPサーバーに対して認証された場合にJWTトークンを返すようにSpringを構成しようとしています。以下のユースケースを検討してください。

enter image description here

上の図では、Bearerでリクエストをチェック/フィルターで除外するようにWebSecurityを構成しています。以下のコードを参照してください

WebSecurityConfig.Java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    JwtAuthorizationTokenFilter authenticationTokenFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Configure Web Security
        // Allow only /auth/
        // Disallow all others
        http
        .csrf().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers(HttpMethod.POST,
                     "/auth/**")
        .permitAll()
        .anyRequest().authenticated();      

        //Custom JWT 
        http.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        // disable page caching
        http.headers().cacheControl();

    }
}

AuthCtrl.Java

@RestController
@RequestMapping("auth")
public class AuthCtrl {

    private static final Logger logger = LoggerFactory.getLogger(AuthCtrl.class);

    @Autowired
    @Qualifier("authenticationManagerImpl")
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    @Qualifier("userDetailsServiceImpl")
    private UserDetailsService userDetailsService;

    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) 
    public @ResponseBody String post(@RequestBody Map<String, String> credentials) {
        logger.info("POST: {} | {} ",credentials.get("username"), credentials.get("password"));
        String username = credentials.get("username");
        String password = credentials.get("password");

        Objects.requireNonNull(username);
        Objects.requireNonNull(password);

        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
            // Reload password post-security so we can generate the token
            final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            final String token = jwtTokenUtil.generateToken(userDetails);
            return token;
        } catch (DisabledException e) {
            throw new AuthenticationException("User is disabled!", e);
        } catch (BadCredentialsException e) {
            throw new AuthenticationException("Bad credentials!", e);
        }
    }

    @ExceptionHandler({AuthenticationException.class})
    public ResponseEntity<String> handleAuthenticationException(AuthenticationException e) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());
    }
}

上記の構成は、私が見た youtube ガイドと、 git のデモソースからのプルに基づいています。大きな助け!、所有者へのクレジット。フィルタがどのように機能するかを理解しました。

上記のソースは、保護されているすべてのAPIを既に除外し、許可されていない場合は応答として許可されていないものを送り返します。匿名でアクセスできる唯一のAPIは、認証API /authです。すでにリクエストを受信し、Webフィルターを通過できます。

しかし、LDAPサーバーへの上記のリクエストを認証し、JWTトークンを送信する方法を完全に理解することはできません。私が読んだガイドでは、彼らはデータベース上のユーザー情報を取得しています。

WebConfigurationのLDAP構成に関するいくつかのドキュメントを読みましたが、現在のフィルターに関連付けることができません。

3
lemoncodes

Spring4を使用して作成した以下のリンクを確認してください。

クラスパス上の.ldifファイルの代わりに、独自のLDAPサーバーを構成します。

https://github.com/merugu/springsecurity/tree/master/ldapauthenticationjwttoken

唯一の違いは、Spring 5の場合、Bcryptpasswordencoderなどの高度なパスワードエンコードアルゴリズムを使用する必要があることです。LDAPpasswordEncoderは非推奨です。

ハッピーコーディング!

5
Amit