我尝试使用spring-boot,oauth2和spring security执行登录过程。我实现了自定义userdetails服务。
这里是代码:
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
private final UserService userService;
@Autowired
public CustomUserDetailsService(UserService userService) {
this.userService = userService;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
if (user == null)
throw new UsernameNotFoundException(String.format("User %s does not exist!", username));
return new UserRepositoryUserDetails(user);
}
private final static class UserRepositoryUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
private UserRepositoryUserDetails(User user) {
super(user);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
// another methods
@Override
public boolean isEnabled() { return super.isEnabled(); }
}
}
用户实体:
@Entity
@Table
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "id", columnDefinition = "VARCHAR(50)")
private String userUUId;
// another parametes
@Column(nullable = false, columnDefinition = "TINYINT DEFAULT false")
@Type(type = "org.hibernate.type.NumericBooleanType")
private boolean enabled;
public User() {
}
public User(User user) {
super();
this.userUUId = user.getUserUUId();
this.roles = user.getRoles();
this.name = user.getName();
this.email = user.getEmail();
this.enabled = isEnabled();
this.password = user.getPassword();
}
// ...
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
安全配置:
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
授权服务器配置的一部分:
@Configuration
@EnableAuthorizationServer
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Bean(name = "tokenStore")
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore())
.authenticationManager(authenticationManager)
.userDetailsService(customUserDetailsService);
}
这里是错误日志:
type=AUTHENTICATION_FAILURE, data={type=org.springframework.security.authentication.DisabledException, message=User is disabled}]
[2016-08-25 09:23:17.774] boot - 21158 INFO [http-nio-8443-exec-1] --- TokenEndpoint: Handling error: InvalidGrantException, User is disabled
[2016-08-25 09:23:17.832] boot - 21158 DEBUG [http-nio-8443-exec-1] --- OrderedRequestContextFilter: Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@6ea0e0af
[2016-08-25 09:23:17.837] boot - 21158 ERROR [http-nio-8443-exec-4] --- EndpointsAuthentification: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
[2016-08-25 09:23:17.839] boot - 21158 DEBUG [http-nio-8443-exec-4] --- OrderedRequestContextFilter: Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@4afe7f7
[2016-08-25 09:23:17.840] boot - 21158 ERROR [http-nio-8443-exec-4] --- [dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.x.server.controller.LoginController.login(LoginController.java:76)
但我相信,用户帐户已启用。对user.isEnabled的调用返回true,但框架无法检测到它。
有什么想法吗? 干杯
答案 0 :(得分:1)
数据库中的已启用字段可能 null 或 false
答案 1 :(得分:1)
org.springframework.security.authentication.DisabledException
的{{1}}方法返回isEnabled()
时抛出UserDetails
。
从您的实现中,false
中的User user = userService.findByUsername(username);
正在从数据库中获取其CustomUserDetailsService
属性为enabled
的用户。
找到一种将其更改为false
的方法。
答案 2 :(得分:0)
在您的NULL
类中,UserDetailsImpl
必须返回true;
isEnabled