簡體   English   中英

Spring 安全 UserDetailsService 拋出 UsernameNotFoundException

[英]Spring Security UserDetailsService throws UsernameNotFoundException

在 Spring Security 中,它們會自動將輸入的用戶名和密碼與數據庫保存的用戶名和密碼進行匹配。 當密碼不匹配時,它會返回錯誤的憑據。 但是,在我的代碼中,據我所知,如果用戶名也與數據庫保存的用戶名不匹配,他們應該返回錯誤的憑據。 但是,在我的代碼中,僅當用戶名正確且密碼錯誤時才會顯示錯誤憑證,並且當用戶名不在數據庫中時會拋出 usernmaenotfoundexception。

我知道我在 loaduserByusername 中寫了 usernamenotfoundexception。 但是,是否應該首先從數據庫中檢查用戶名是否匹配,如果錯誤則返回錯誤的憑據? 我從 inte.net 找到了 userdetailservice,大多數人都是這樣寫代碼的。 那怎么知道id不匹配,,?

太感謝了

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;
        
    }

}

安全上下文.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

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);
    }
}

我想念 spring 安全流程的理解。 它實際上在 userdetailservice 運行后檢查 id 和密碼。 所以,我只是刪除了 throws new UsernameNotFoundException 並 return new CustomMemDetails(); 然后在登錄失敗 handler.java 中檢查異常是 DisabledException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM