前言
successhandler和failurehandler是spring security中两个较为强大的用来处理登录成功和失败的回调函数,通过它们两个我们就可以自定义一些前后端数据的交互。
successhandler
该方法有三个参数
req
:相当与httpservletrequestres
:相当与httpservletresposeauthentication
:这里保存了我们登录后的用户信息
进行如下配置
.successhandler((req, resp, authentication) -> { object principal = authentication.getprincipal(); resp.setcontenttype("application/json;charset=utf-8"); printwriter out = resp.getwriter(); out.write(new objectmapper().writevalueasstring(principal)); out.flush(); out.close(); })
配置类代码
package com.scexample.sc.config; import com.fasterxml.jackson.databind.objectmapper; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.builders.websecurity; import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter; import org.springframework.security.crypto.password.nooppasswordencoder; import org.springframework.security.crypto.password.passwordencoder; import org.springframework.security.web.util.matcher.antpathrequestmatcher; import java.io.printwriter; @configuration public class securityconfig extends websecurityconfigureradapter { @bean passwordencoder passwordencoder(){ return nooppasswordencoder.getinstance(); } @override protected void configure(authenticationmanagerbuilder auth) throws exception { auth.inmemoryauthentication() .withuser("xiaoming") .password("123456").roles("admin"); } @override public void configure(websecurity web) throws exception { web.ignoring().antmatchers("/js/**","/css/**","/images/**"); //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。 } @override protected void configure(httpsecurity http) throws exception { http.authorizerequests() .anyrequest().authenticated() .and() .formlogin() .loginpage("/aaa.html") .loginprocessingurl("/logintest") .usernameparameter("name") .passwordparameter("passwd") .successhandler((req, res, authentication) -> { object principal = authentication.getprincipal(); res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(new objectmapper().writevalueasstring(principal)); out.flush(); out.close(); }) .permitall() .and() .csrf().disable() ); } }
再次登录后
failurehandler
该方法有三个参数
req
:相当与httpservletrequestres
:相当与httpservletresposee
:这里保存了我们登录失败的原因
异常种类:
lockedexception
账户锁定credentialsexpiredexception
密码过期accountexpiredexception
账户过期disabledexception
账户被禁止badcredentialsexception
用户名或者密码错误
.failurehandler((req, res, e) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(e.getmessage()); out.flush(); out.close(); })
配置类代码:
package com.scexample.sc.config; import com.fasterxml.jackson.databind.objectmapper; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.builders.websecurity; import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter; import org.springframework.security.crypto.password.nooppasswordencoder; import org.springframework.security.crypto.password.passwordencoder; import org.springframework.security.web.util.matcher.antpathrequestmatcher; import java.io.printwriter; @configuration public class securityconfig extends websecurityconfigureradapter { @bean passwordencoder passwordencoder(){ return nooppasswordencoder.getinstance(); } @override protected void configure(authenticationmanagerbuilder auth) throws exception { auth.inmemoryauthentication() .withuser("xiaoming") .password("123456").roles("admin"); } @override public void configure(websecurity web) throws exception { web.ignoring().antmatchers("/js/**","/css/**","/images/**"); //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。 } @override protected void configure(httpsecurity http) throws exception { http.authorizerequests() .anyrequest().authenticated() .and() .formlogin() .loginpage("/aaa.html") .loginprocessingurl("/logintest") .usernameparameter("name") .passwordparameter("passwd") .successhandler((req, res, authentication) -> { object principal = authentication.getprincipal(); res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(new objectmapper().writevalueasstring(principal)); out.flush(); out.close(); }) .failurehandler((req, res, e) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(e.getmessage()); out.flush(); out.close(); }) .permitall() .and() .csrf().disable() } }
未认证处理方法
spring security默认情况下,如果认证不成功,直接重定向到登录页面。
但是项目中,我们有的时候不需要这样,我们需要在前端进行判断 ,然后再决定进行其他的处理,那我们就可以用authenticationentrypoint这个接口进行自定义了,取消它的默认重定向行为。
该方法有三个参数
req
:相当与httpservletrequestres
:相当与httpservletresposeauthexception
:指的就是我们未认证的exception
.csrf().disable() .exceptionhandling() .authenticationentrypoint((req, res, authexception) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write("检测到未登录状态,请先登录"); out.flush(); out.close(); }
配置类代码
package com.scexample.sc.config; import com.fasterxml.jackson.databind.objectmapper; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.builders.websecurity; import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter; import org.springframework.security.crypto.password.nooppasswordencoder; import org.springframework.security.crypto.password.passwordencoder; import org.springframework.security.web.util.matcher.antpathrequestmatcher; import java.io.printwriter; @configuration public class securityconfig extends websecurityconfigureradapter { @bean passwordencoder passwordencoder(){ return nooppasswordencoder.getinstance(); } @override protected void configure(authenticationmanagerbuilder auth) throws exception { auth.inmemoryauthentication() .withuser("xiaoming") .password("123456").roles("admin"); } @override public void configure(websecurity web) throws exception { web.ignoring().antmatchers("/js/**","/css/**","/images/**"); //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。 } @override protected void configure(httpsecurity http) throws exception { http.authorizerequests() .anyrequest().authenticated() .and() .formlogin() .loginpage("/aaa.html") .loginprocessingurl("/logintest") .usernameparameter("name") .passwordparameter("passwd") .successhandler((req, res, authentication) -> { object principal = authentication.getprincipal(); res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(new objectmapper().writevalueasstring(principal)); out.flush(); out.close(); }) .failurehandler((req, res, e) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(e.getmessage()); out.flush(); out.close(); }) .permitall() .and() .csrf().disable() .exceptionhandling() .authenticationentrypoint((req, res, authexception) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write("检测到未登录状态,请先登录"); out.flush(); out.close(); } ); } }
注销登录
.logoutsuccesshandler((req, res, authentication) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write("注销成功"); out.flush(); out.close(); })
配置类代码:
package com.scexample.sc.config; import com.fasterxml.jackson.databind.objectmapper; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder; import org.springframework.security.config.annotation.web.builders.httpsecurity; import org.springframework.security.config.annotation.web.builders.websecurity; import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter; import org.springframework.security.crypto.password.nooppasswordencoder; import org.springframework.security.crypto.password.passwordencoder; import org.springframework.security.web.util.matcher.antpathrequestmatcher; import java.io.printwriter; @configuration public class securityconfig extends websecurityconfigureradapter { @bean passwordencoder passwordencoder(){ return nooppasswordencoder.getinstance(); } @override protected void configure(authenticationmanagerbuilder auth) throws exception { auth.inmemoryauthentication() .withuser("xiaoming") .password("123456").roles("admin"); } @override public void configure(websecurity web) throws exception { web.ignoring().antmatchers("/js/**","/css/**","/images/**"); //这个是用来忽略一些url地址,对其不进行校验,通常用在一些静态文件中。 } @override protected void configure(httpsecurity http) throws exception { http.authorizerequests() .anyrequest().authenticated() .and() .formlogin() .loginpage("/aaa.html") .loginprocessingurl("/logintest") .usernameparameter("name") .passwordparameter("passwd") .successhandler((req, res, authentication) -> { object principal = authentication.getprincipal(); res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(new objectmapper().writevalueasstring(principal)); out.flush(); out.close(); }) .failurehandler((req, res, e) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write(e.getmessage()); out.flush(); out.close(); }) .permitall() .and() .logout() .logouturl("/logout") .logoutsuccesshandler((req, res, authentication) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write("注销成功"); out.flush(); out.close(); }) .permitall() .and() .csrf().disable() .exceptionhandling() .authenticationentrypoint((req, res, authexception) -> { res.setcontenttype("application/json;charset=utf-8"); printwriter out = res.getwriter(); out.write("检测到未登录状态,请先登录"); out.flush(); out.close(); } ); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论