简体   繁体   English

Spring 安全 UserDetailsService 抛出 UsernameNotFoundException

[英]Spring Security UserDetailsService throws UsernameNotFoundException

In the Spring Security, they automatically match input username and password with the DB saved username and password.在 Spring Security 中,它们会自动将输入的用户名和密码与数据库保存的用户名和密码进行匹配。 It returns bad credential when password is not matched.当密码不匹配时,它会返回错误的凭据。 However, in my code, as long as I know, if the username also does not match with DB saved username they should return bad credential.但是,在我的代码中,据我所知,如果用户名也与数据库保存的用户名不匹配,他们应该返回错误的凭据。 However, in my code, bad credential are shown only when username is correct and password is wrong and when username is not in DB it throws usernmaenotfoundexception.但是,在我的代码中,仅当用户名正确且密码错误时才会显示错误凭证,并且当用户名不在数据库中时会抛出 usernmaenotfoundexception。

I know I wrote usernamenotfoundexception in loaduserByusername.我知道我在 loaduserByusername 中写了 usernamenotfoundexception。 However, should it be first to check from DB whether username is matched and if it is wrong then bad credentials should be returned?但是,是否应该首先从数据库中检查用户名是否匹配,如果错误则返回错误的凭据? I found userdetailservice from inte.net and most of people wrote the code this way.我从 inte.net 找到了 userdetailservice,大多数人都是这样写代码的。 Then how should we know id not matched.,,?那怎么知道id不匹配,,?

Thank you so much太感谢了

UserDeatilSerivce.java UserDetailService.java

package com.group6.shopping.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.group6.shopping.members.dao.MembersDAO;
import org.springframework.ui.Model;

public class CustomMemDetailsService implements UserDetailsService{
    
    @Autowired
    MembersDAO membersDAO;
    
    @Override
    public UserDetails loadUserByUsername(String memId) {
        System.out.println("loaduserByusername");
        CustomMemDetails members = null;
        
        try {
            
            members = membersDAO.getMemById(memId);

            if(members == null) {
                 throw new UsernameNotFoundException("username " + memId + " not found");
            }
            System.out.println("**************Found user***************");
            System.out.println("id : " + members.getUsername());
            return members;
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return members;
        
    }

}

security-context.xml安全上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
        
    <security:http pattern="/resources/**" security="none"/>

    <security:http>
        <security:intercept-url pattern="/everyone/**" access="permitAll"/>
        <security:intercept-url pattern="/member/**" access="hasRole('ROLE_MEMBER')"/>
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <security:form-login login-page="/everyone/login"
                             login-processing-url="/everyone/login/loginProcess"
                             default-target-url="/"
                             authentication-failure-handler-ref="loginFailureHandler"/>
        <!-- 최대 한 개의 세션만 생성되도록 -->
        <security:session-management invalid-session-url="/everyone/login">
            <security:concurrency-control max-sessions="1"
                                          expired-url="/everyone/login"
                                          error-if-maximum-exceeded="true" />
        </security:session-management>
    </security:http>

    <security:authentication-manager>   
        <security:authentication-provider user-service-ref="customMemService">
            <security:password-encoder hash="bcrypt"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
    <bean id="loginFailureHandler" class="com.group6.shopping.security.LoginFailureHandler"/>

    <context:component-scan base-package="com.group6.shopping.security" />
    <bean id="customMemService" class="com.group6.shopping.security.CustomMemDetailsService" />
</beans>

LoginFailureHandler.java LoginFailureHandler.java

package com.group6.shopping.security;

import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        String msg = "";

        if(exception instanceof UsernameNotFoundException){
            System.out.println("username error");
            msg = "Wrong id or password. Please re-enter";
        }else if (exception instanceof BadCredentialsException){
            System.out.println("bad credential");
            msg = "Wrong id or password. Please re-enter";
        }

        request.setAttribute("msg", msg);
        request.getRequestDispatcher("/everyone/login?error").forward(request, response);
    }
}

I had miss understanding of spring security flow.我想念 spring 安全流程的理解。 It actually checks id and password after userdetailservice is ran.它实际上在 userdetailservice 运行后检查 id 和密码。 So, I just delete throws new UsernameNotFoundException and return new CustomMemDetails();所以,我只是删除了 throws new UsernameNotFoundException 并 return new CustomMemDetails(); then in login failure handler.java just check exception is DisabledException然后在登录失败 handler.java 中检查异常是 DisabledException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM