如果提供的用户名密码准确,我想生成JWT。我有userdetailservice
,我正在使用AbstractUserDetailsAuthenticationProvider
。这是我的代码:
public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {
public JwtAuthenticationTokenFilter() {
super("/rest/**");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
String header = httpServletRequest.getHeader("Authorisation");
if (header == null || !header.startsWith("Token")) {
throw new RuntimeException("JWT Token is missing");
}
String authenticationToken = header.substring(6);
JwtAuthenticationToken token = new JwtAuthenticationToken(authenticationToken);
return getAuthenticationManager().authenticate(token);
}
当我尝试登录时,即使密码错误也会返回JWT。
@RestController
@RequestMapping("/token")
public class TokenController {
private JwtGenerator jwtGenerator;
public TokenController(JwtGenerator jwtGenerator) {
this.jwtGenerator = jwtGenerator;
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String createAuthenticationToken(
@RequestBody User user,
HttpServletResponse response) throws AuthenticationException, IOException {
return jwtGenerator.generate(user);
}
我的理解是当用户尝试登录时,用户详细信息服务通过用户名加载验证用户的身份,因此我不知道为什么它不起作用。
这是我的安全配置的一部分:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("**/rest/**").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(entryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
http.headers().cacheControl();
}
答案 0 :(得分:1)
您的问题是,当您调用请求登录时,您不是身份验证用户,您只是在创建令牌,而不是在检查密码是否有效,因此首先在登录服务中您必须添加以下代码: / p>
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<?> login(@RequestBody LoginUser loginUser) throws AuthenticationException {
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginUser.getUsername(),
loginUser.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
final String token = jwtTokenUtil.generateToken(authentication);
User user = userService.getUserByUsername(loginUser.getUsername());
user.setToken(token);
return ResponseEntity.ok(user);
}
LoginUser是一个Java类,只有两个字段,用户名和密码带有构造函数,这两个字段的获取器和设置器。
final Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginUser.getUsername(),
loginUser.getPassword()
)
);
此代码将检查用户名和密码的有效性,它将自身转到userdetails类中定义的loadbyusername函数,如果用户名或密码错误,api将返回错误的凭据错误,但为此您需要编写额外的代码。
创建课程:
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint,
Serializable {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
,然后在安全配置类中的JwtAuthenticationEntryPoint类的初始化对象之后,如下所示:
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
并将此代码添加到Web安全配置类的configure函数中:
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler)