spring-security 個性化用戶認證流程——自定義登陸成功/失敗的處理

1.自定義登陸成功處理
什麼須要自定義登陸成功處理,由於登陸行爲不止只有一種,有多是ajax請求,而默認的則是form提交跳轉的行爲,這個時候就不是咱們想要的一種結果。html

若是自定義登陸成功以後的行爲?只須要實現AuthenticationSuccessHandler接口ajax

@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler{
    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
    @Autowired
    private ObjectMapper objectMapper;

    //登陸成功以後會被調用
    //Authentication用來封裝咱們的認證信息,包括髮起認證請求裏的認證信息(IP,Session,以及認證經過以後UserDetails的實現類的信息),
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        logger.info("登陸成功");
        //把authentication返回給前臺
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }

}

再修改BrowserSecurityConfig類的配置信息
spring-security 個性化用戶認證流程——自定義登陸成功/失敗的處理
訪問請求:http://localhost:8080/sign.html ,登陸成功以後,會把用戶的信息所有返回spring

{
authorities: [
{
authority: "admin"  //該用戶的角色信息
}
],
details: {
remoteAddress: "0:0:0:0:0:0:0:1",  //發起請求的IP
sessionId: null
},
authenticated: true,
principal: {   //principal就是UserDetails的實現類裏面的信息
username: "admin",
password: "$2a$10$WPv2.mXiAPEaOXjAHP9jYuLNfbGT1Nk99Ix2fn351gZGKeEPiOTQW",
accountNonExpired: true,
accountNonLocked: true,
credentialsNonExpired: true,
enabled: true,
authorities: [
{
authority: "admin"
}
]
},
credentials: null,
name: "admin"
}

1.自定義登陸錯誤處理
實現AuthenticationFailureHandler接口json

@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    //AuthenticationException記錄,用戶名沒找到,密碼沒匹配上等信息  認證過程當中全部發生的錯誤
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        logger.info("登陸失敗");
        //把exception返回給前臺
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(exception));
    }

}

AuthenticationException下的異常子類
spring-security 個性化用戶認證流程——自定義登陸成功/失敗的處理session

一樣也須要配置BrowserSecurityConfig配置類app

spring-security 個性化用戶認證流程——自定義登陸成功/失敗的處理

訪問請求:http://localhost:8080/sign.html ,登陸失敗以後,會把異常信息返回ide

spring-security 個性化用戶認證流程——自定義登陸成功/失敗的處理

2.可配置化
須要把它作成可配置化的,有些應用倒是是form提交方式,應該須要更靈活一些
BrowserProperties中定義一下跳轉方式code

public enum LoginType {
    REDIRECT, //跳轉
    JSON;     //JSON
}

public class BrowserProperties {
    //標準的登陸頁面,若是其餘項目沒有配置則使用默認的登陸配置
    private String loginPage = "/sign.html";
    private LoginType loginType = LoginType.JSON;//默認返回json
    //get/set
}

既然須要跳轉頁面的這種方式,這個時候就不能僅僅實現Success/FailHandler接口這樣了。orm

@Component("myAuthenticationSuccessHandler")
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SecurityProperties securityProperties;//判斷咱們的請求數據的返回方式json/redirect

    //登陸成功以後會被調用
    //Authentication用來封裝咱們的認證信息,包括髮起認證請求裏的認證信息(IP,Session,以及認證經過以後UserDetails的實現類的信息),
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        logger.info("登陸成功");
        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
            //把authentication返回給前臺
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(authentication));
        }else {
            //跳轉
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }

}

@Component("myAuthenticationFailHandler")
public class MyAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {

    private static final Logger logger = LoggerFactory.getLogger(MyAuthenticationFailHandler.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SecurityProperties securityProperties;

    //AuthenticationException記錄,用戶名沒找到,密碼沒匹配上等信息  認證過程當中全部發生的錯誤
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {
        logger.info("登陸失敗");
        if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {            
            //把exception返回給前臺
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(exception));
        }else {
            //跳轉,即返回頁面
            super.onAuthenticationFailure(request, response, exception);
        }
    }

}

訪問請求:http://localhost:8080/sign.html ,登陸成功和失敗都會返回json的方式htm

當更改完配置:

LoginType.REDIRECT;

再次訪問請求:http://localhost:8080/sign.html ,登陸成功和失敗都會返回跳轉的方式

相關文章
相關標籤/搜索