【问题标题】:Spring security userdetails: org.springframework.security.authentication.DisabledExceptionSpring 安全用户详细信息:org.springframework.security.authentication.DisabledException
【发布时间】:2017-01-01 12:51:43
【问题描述】:

我尝试使用 spring-boot、oauth2 和 spring security 执行登录过程。我实现了一个自定义用户详细信息服务。

代码如下:

@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,但框架检测不到。

有什么想法吗? 干杯

【问题讨论】:

  • 您可以发布用户代码吗?

标签: java spring spring-security spring-boot spring-oauth2


【解决方案1】:

在您的 UserDetailsImpl 类中,isEnabled 必须返回 true;

@Override
public boolean isEnabled() {
    return true;
}

【讨论】:

    【解决方案2】:

    UserDetailsisEnabled() 方法返回false 时,会抛出org.springframework.security.authentication.DisabledException

    根据您的实现,CustomUserDetailsService 中的User user = userService.findByUsername(username); 正在从数据库中获取enabled 属性为false 的用户。 想办法把它改成true

    【讨论】:

      【解决方案3】:

      可能数据库中的 enabled 字段为 nullfalse

      【讨论】:

        猜你喜欢
        • 2017-10-02
        • 1970-01-01
        • 2012-04-03
        • 2019-03-08
        • 2013-03-15
        • 2020-07-24
        • 2012-05-23
        • 2017-08-04
        • 1970-01-01
        相关资源
        最近更新 更多