Spring Security 入门(3-11)Spring Security 的使用-自定义登录验证和回调地址
- 配置文件 security-ns.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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
- //需要过滤不被拦截的请求
- <security:http pattern="/openapi/**" security="none" />
- <security:http pattern="/useraccounts/userprofile.json" security="none" />
- <security:http pattern="/useraccounts/register**" security="none" />
- //entry-point-ref 配置自定义登录
- <security:http auto-config="false" entry-point-ref="authenticationEntryPoint">
- <security:intercept-url pattern="/backManage/**" access="ROLE_BACK_USER" />
- <security:intercept-url pattern="/mall/**" access="ROLE_BACK_USER" />
- <security:intercept-url pattern="/thirdUser/**" access="ROLE_USER" />
- <security:intercept-url pattern="/useraccounts/**" access="ROLE_USER" />
- <security:intercept-url pattern="/cart/**.html" access="ROLE_USER" />
- <security:intercept-url pattern="/ticket/**" access="ROLE_USER,ROLE_BACK_USER" />
- <security:intercept-url pattern="/order/**" access="ROLE_USER" />
- <security:intercept-url pattern="/comment/**" access="ROLE_USER" />
- <security:intercept-url pattern="/personal/**" access="ROLE_USER" />
- <security:intercept-url pattern="/favorite/**" access="ROLE_USER" />
- //需要替换的Filter顺序,配置自定义custom-filter时必须蔣auto-config="false",不然会报已经存在同样的过滤器错误
- <security:custom-filter ref="myLoginFilter" position="FORM_LOGIN_FILTER" />
- //登出配置
- <security:logout logout-success-url="${local.service.url}"/>
- </security:http>
- //密码加密工具类
- <bean id="encoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>
- //认证管理器
- <security:authentication-manager alias="authenticationManager">
- //UserDetailsService实现 主要用于用户的查询
- <security:authentication-provider user-service-ref="userLoginService">
- <security:password-encoder ref="encoder">
- </security:password-encoder>
- </security:authentication-provider>
- </security:authentication-manager>
- <bean id="myLoginFilter" class="com.sale114.www.sercurity.MyUsernamePasswordAuthenticationFilter">
- <property name="authenticationManager" ref="authenticationManager"/>
- <property name="authenticationFailureHandler" ref="failureHandler"/>
- <property name="authenticationSuccessHandler" ref="successHandler"/>
- </bean>
- //成功登录后
- <bean id="successHandler" class="com.sale114.www.sercurity.MySavedRequestAwareAuthenticationSuccessHandler">
- <property name="defaultTargetUrl" value="${local.service.url}"/>
- </bean>
- //登录失败
- <bean id="failureHandler" class="com.sale114.www.sercurity.MySimpleUrlAuthenticationFailureHandler">
- <property name="defaultFailureUrl" value="${local.service.url}/login.html?validated=false"/>
- </bean>
- <bean id="authenticationEntryPoint"
- class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
- <property name="loginFormUrl" value="${local.service.url}/login.html" />
- </bean>
- </beans>
- 2 UserLoginServiceImpl 查询用户实现类
- @Named("userLoginService")
- public class UserLoginServiceImpl implements UserDetailsService ,LoginService{
- @Inject
- private UserLoginDAO userLoginDAO;
- @Override
- public WrappedUserLogin getUserLogin() {
- try {
- WrappedUserLogin wrappedUserLogin = (WrappedUserLogin) SecurityContextHolder
- .getContext().getAuthentication().getPrincipal();
- return wrappedUserLogin;
- } catch (Exception e) {
- return null;
- }
- }
- @Override
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException {
- System.out.println("用户名-------------"+username);
- UserLogin userLogin = null;
- if(username != null && !"".equals(username)&& username.indexOf("@") > 0){
- userLogin = userLoginDAO.findByEmail(username);
- username = userLogin.getNick();
- }else{
- userLogin = userLoginDAO.findByNick(username);
- }
- System.out.println("user is null ---"+userLogin.getUserType());
- String nick = userLogin.getNick();
- String email = userLogin.getEmail();
- String mobile = userLogin.getMobile();
- int userType = userLogin.getUserType();
- List<GrantedAuthority> resultAuths = new ArrayList<GrantedAuthority>();
- // 前台用户
- if (userType == 1) {
- resultAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
- } else {
- resultAuths.add(new SimpleGrantedAuthority("ROLE_BACK_USER"));
- }
- return new WrappedUserLogin(userLogin.getId(), email, nick, mobile, userLogin.getPassword(), userType,resultAuths);
- }
- }
- 3 重写用户名密码验证
- public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
- //用户名
- public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
- //密码
- public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
- //需要回调的URL 自定义参数
- public static final String SPRING_SECURITY_FORM_REDERICT_KEY = "spring-security-redirect";
- /**
- * @deprecated If you want to retain the username, cache it in a customized {@code AuthenticationFailureHandler}
- */
- @Deprecated
- public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
- private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
- private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
- private String redirectParameter = SPRING_SECURITY_FORM_REDERICT_KEY;
- private boolean postOnly = true;
- //~ Constructors ===================================================================================================
- public MyUsernamePasswordAuthenticationFilter() {
- super();
- }
- //~ Methods ========================================================================================================
- public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
- if (postOnly && !request.getMethod().equals("POST")) {
- throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
- }
- String username = obtainUsername(request);
- String password = obtainPassword(request);
- String redirectUrl = obtainRedercitUrl(request);
- if (username == null) {
- username = "";
- }
- if (password == null) {
- password = "";
- }
- //自定义回调URL,若存在则放入Session
- if(redirectUrl != null && !"".equals(redirectUrl)){
- request.getSession().setAttribute("callCustomRediretUrl", redirectUrl);
- }
- username = username.trim();
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
- // Allow subclasses to set the "details" property
- setDetails(request, authRequest);
- return this.getAuthenticationManager().authenticate(authRequest);
- }
- /**
- * Enables subclasses to override the composition of the password, such as by including additional values
- * and a separator.<p>This might be used for example if a postcode/zipcode was required in addition to the
- * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
- * <code>AuthenticationDao</code> will need to generate the expected password in a corresponding manner.</p>
- *
- * @param request so that request attributes can be retrieved
- *
- * @return the password that will be presented in the <code>Authentication</code> request token to the
- * <code>AuthenticationManager</code>
- */
- protected String obtainPassword(HttpServletRequest request) {
- return request.getParameter(passwordParameter);
- }
- /**
- * Enables subclasses to override the composition of the username, such as by including additional values
- * and a separator.
- *
- * @param request so that request attributes can be retrieved
- *
- * @return the username that will be presented in the <code>Authentication</code> request token to the
- * <code>AuthenticationManager</code>
- */
- protected String obtainUsername(HttpServletRequest request) {
- return request.getParameter(usernameParameter);
- }
- protected String obtainRedercitUrl(HttpServletRequest request) {
- return request.getParameter(redirectParameter);
- }
- /**
- * Provided so that subclasses may configure what is put into the authentication request's details
- * property.
- *
- * @param request that an authentication request is being created for
- * @param authRequest the authentication request object that should have its details set
- */
- protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
- authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
- }
- /**
- * Sets the parameter name which will be used to obtain the username from the login request.
- *
- * @param usernameParameter the parameter name. Defaults to "j_username".
- */
- public void setUsernameParameter(String usernameParameter) {
- Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
- this.usernameParameter = usernameParameter;
- }
- /**
- * Sets the parameter name which will be used to obtain the password from the login request..
- *
- * @param passwordParameter the parameter name. Defaults to "j_password".
- */
- public void setPasswordParameter(String passwordParameter) {
- Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
- this.passwordParameter = passwordParameter;
- }
- /**
- * Defines whether only HTTP POST requests will be allowed by this filter.
- * If set to true, and an authentication request is received which is not a POST request, an exception will
- * be raised immediately and authentication will not be attempted. The <tt>unsuccessfulAuthentication()</tt> method
- * will be called as if handling a failed authentication.
- * <p>
- * Defaults to <tt>true</tt> but may be overridden by subclasses.
- */
- public void setPostOnly(boolean postOnly) {
- this.postOnly = postOnly;
- }
- }
- 4 SimpleUrlAuthenticationSuccessHandler重写
- public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
- @Value(value = "${local.service.url}")
- private String LOCAL_SERVER_URL;
- protected final Log logger = LogFactory.getLog(this.getClass());
- private RequestCache requestCache = new HttpSessionRequestCache();
- @Override
- public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
- Authentication authentication) throws ServletException, IOException {
- SavedRequest savedRequest = requestCache.getRequest(request, response);
- if (savedRequest == null) {
- System.out.println("savedRequest is null ");
- //用户判断是否要使用上次通过session里缓存的回调URL地址
- int flag = 0;
- //通过提交登录请求传递需要回调的URL callCustomRediretUrl
- if(request.getSession().getAttribute("callCustomRediretUrl") != null && !"".equals(request.getSession().getAttribute("callCustomRediretUrl"))){
- String url = String.valueOf(request.getSession().getAttribute("callCustomRediretUrl"));
- //若session 存在则需要使用自定义回调的URL 而不是缓存的URL
- super.setDefaultTargetUrl(url);
- super.setAlwaysUseDefaultTargetUrl(true);
- flag = 1;
- request.getSession().setAttribute("callCustomRediretUrl", "");
- }
- //重设置默认URL为主页地址
- if(flag == 0){
- super.setDefaultTargetUrl(LOCAL_SERVER_URL);
- }
- super.onAuthenticationSuccess(request, response, authentication);
- return;
- }
- //targetUrlParameter 是否存在
- String targetUrlParameter = getTargetUrlParameter();
- if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
- requestCache.removeRequest(request, response);
- super.setAlwaysUseDefaultTargetUrl(false);
- super.setDefaultTargetUrl("/");
- super.onAuthenticationSuccess(request, response, authentication);
- return;
- }
- //清除属性
- clearAuthenticationAttributes(request);
- // Use the DefaultSavedRequest URL
- String targetUrl = savedRequest.getRedirectUrl();
- logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl);
- if(targetUrl != null && "".equals(targetUrl)){
- targetUrl = LOCAL_SERVER_URL;
- }
- getRedirectStrategy().sendRedirect(request, response, targetUrl);
- }
- public void setRequestCache(RequestCache requestCache) {
- this.requestCache = requestCache;
- }
- }
- 5 认证失败控制类重写
- /**
- * <tt>AuthenticationFailureHandler</tt> which performs a redirect to the value of the {@link #setDefaultFailureUrl
- * defaultFailureUrl} property when the <tt>onAuthenticationFailure</tt> method is called.
- * If the property has not been set it will send a 401 response to the client, with the error message from the
- * <tt>AuthenticationException</tt> which caused the failure.
- * <p>
- * If the {@code useForward} property is set, a {@code RequestDispatcher.forward} call will be made to
- * the destination instead of a redirect.
- *
- * @author Luke Taylor
- * @since 3.0
- */
- public class MySimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler{
- protected final Log logger = LogFactory.getLog(getClass());
- private String defaultFailureUrl;
- private boolean forwardToDestination = false;
- private boolean allowSessionCreation = true;
- private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
- @Value(value = "${local.service.url}")
- private String LOCAL_SERVER_URL;
- public MySimpleUrlAuthenticationFailureHandler() {
- }
- public MySimpleUrlAuthenticationFailureHandler(String defaultFailureUrl) {
- setDefaultFailureUrl(defaultFailureUrl);
- }
- /**
- * Performs the redirect or forward to the {@code defaultFailureUrl} if set, otherwise returns a 401 error code.
- * <p>
- * If redirecting or forwarding, {@code saveException} will be called to cache the exception for use in
- * the target view.
- */
- public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException exception) throws IOException, ServletException {
- //认证失败区别前后台:LOGIN URL
- if(request.getParameter("spring-security-redirect") != null){
- request.getSession().setAttribute("callUrlFailure", request.getParameter("spring-security-redirect"));
- }
- //若有loginUrl 则重定向到后台登录界面
- if(request.getParameter("loginUrl") != null && !"".equals(request.getParameter("loginUrl"))){
- defaultFailureUrl = LOCAL_SERVER_URL+"/backlogin.html?validated=false";
- }
- //defaultFailureUrl 默认的认证失败回调URL
- if (defaultFailureUrl == null) {
- logger.debug("No failure URL set, sending 401 Unauthorized error");
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage());
- } else {
- saveException(request, exception);
- if (forwardToDestination) {
- logger.debug("Forwarding to " + defaultFailureUrl);
- request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
- } else {
- logger.debug("Redirecting to " + defaultFailureUrl);
- redirectStrategy.sendRedirect(request, response, defaultFailureUrl);
- }
- }
- }
- /**
- * Caches the {@code AuthenticationException} for use in view rendering.
- * <p>
- * If {@code forwardToDestination} is set to true, request scope will be used, otherwise it will attempt to store
- * the exception in the session. If there is no session and {@code allowSessionCreation} is {@code true} a session
- * will be created. Otherwise the exception will not be stored.
- */
- protected final void saveException(HttpServletRequest request, AuthenticationException exception) {
- if (forwardToDestination) {
- request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
- } else {
- HttpSession session = request.getSession(false);
- if (session != null || allowSessionCreation) {
- request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
- }
- }
- }
- /**
- * The URL which will be used as the failure destination.
- *
- * @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp".
- */
- public void setDefaultFailureUrl(String defaultFailureUrl) {
- this.defaultFailureUrl = defaultFailureUrl;
- }
- protected boolean isUseForward() {
- return forwardToDestination;
- }
- /**
- * If set to <tt>true</tt>, performs a forward to the failure destination URL instead of a redirect. Defaults to
- * <tt>false</tt>.
- */
- public void setUseForward(boolean forwardToDestination) {
- this.forwardToDestination = forwardToDestination;
- }
- /**
- * Allows overriding of the behaviour when redirecting to a target URL.
- */
- public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
- this.redirectStrategy = redirectStrategy;
- }
- protected RedirectStrategy getRedirectStrategy() {
- return redirectStrategy;
- }
- protected boolean isAllowSessionCreation() {
- return allowSessionCreation;
- }
- public void setAllowSessionCreation(boolean allowSessionCreation) {
- this.allowSessionCreation = allowSessionCreation;
- }
- }
Spring Security 入门(3-11)Spring Security 的使用-自定义登录验证和回调地址相关推荐
- Spring Security自定义登录验证,验证码,动态管理uri访问权限,Thymeleaf,限制密码强度、过期、错误密码锁定超时自动解锁、禁用历史密码、新密码和现密码差异要求编辑距离
在本教程中,我将指导您如何编写代码,以使用具有基于表单的身份验证的Spring安全API来保护Spring Boot应用程序中的网页.用户详细信息存储在MySQL数据库中,并使用春季JDBC连接到数据 ...
- Spring Security自定义登录验证及登录返回结果
Spring Security自定义登录验证及登录返回结果 一.功能描述 二.处理逻辑 简单流程 自定义UserDetails 自定义UserDetailsDAO 自定义UserDetailsServ ...
- Spring Cloud入门-Oauth2授权之基于JWT完成单点登录(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 单点登录简介 创建oauth2-client模块 修改授权服务器配置 网页单点登录演示 调用接口单点登录演示 oauth2-client添加权限校 ...
- 普歌-云言团队-Spring Boot入门:环境搭建Spring Boot HelloWorld
Spring Boot入门:环境搭建Spring Boot HelloWorld 前言:SpringBoot 是来简化Spring应用开发, 约定大于配置, 去繁从简, just run就能创建一个独 ...
- Spring Cloud入门系列(1)- Spring生态体系发展史+全系框架介绍
Spring发展史 2000年,Java EE和EJB迅速发展,很多知名公司都是采用此技术方案进行项目开发,但是EJB 属于重量级框架,开发繁琐.于是一个叫Rod Johnson的大佬写了一本叫做&l ...
- Spring Boot入门(11)实现文件下载功能
在这篇博客中,我们将展示如何在Spring Boot中实现文件的下载功能. 还是遵循笔者写博客的一贯风格,简单又不失详细,实用又能让你学会. 本次建立的Spring Boot项目的主要功能 ...
- Spring Boot入门(01):Spring Boot的奋斗成长史
作者:bug菌 博客:CSDN.掘金.infoQ.51CTO等 简介:CSDN/阿里云/华为云/51CTO博客专家,博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金/ ...
- 简单的Spring MVC入门程序,对于Spring mvc工作流程的理解,servlet标签和servlet-mapping 理解,视图解析器
javaweb SpringMvc的组成:jsp,JavaBean,servlet 可以使用Spring所提供的功能 提供了前端控制器DispatcherServlet,不需要细化Servlet 执行 ...
- Spring Boot入门二:Spring Boot版本;
说明: (1)本篇博客主要介绍了Spring Boot版本相关的内容:可以增加自己对Spring Boot的整体了解: 目录 1.Spring Boot的官网,可以看到当前的版本: 2.Spring ...
最新文章
- android weight(权重)的具体分析
- oracle命令导入表
- 小松卡特彼勒无人驾驶_运输量突破20亿吨,卡特彼勒无人驾驶矿卡迎里程碑时刻...
- JMessage Android 端开发详解
- 为什么使用pickle模块
- 查找数据结构相关题目
- struts2:在Action中使用Servlet的API,设置、读取各种内置对象的属性
- 用python念数字_Python-数据类型之数字
- 添加CSS的四种方式
- LeetCode 1953. 你可以工作的最大周数
- JavaSE----数组
- 克隆PDB数据库操作
- JAVA101本土精选,Java101系列文章
- 腾讯云cdn设置 php,腾讯云CDN缓存过期配置问题详解
- automation服务器不能创建对象问题解决
- sql语句根据身份证号获取年龄
- 【转载】Matlab中LMI(线性矩阵不等式)工具箱使用教程
- android 百度地图骑行路线颜色及宽度更改
- 【转】bt5更新源(完整)
- Android 设置边距总结
热门文章
- python 计算时间重叠_Python基于时间信息(即时、间隔)计算项目之间的相似性...
- Verilator简介及其下载安装卸载
- springboot的jsp应该放在哪_在springboot中集成jsp开发
- 计算机教室内网连接不了,校园网登陆不了内网怎么办?校园网登陆不了内网的解决方法...
- oracle 动态sql列转行_SQL优化笔记分享:34条实用经验可别错过!
- linux进去网卡,Linux上使用socket进行网卡抓包
- 吴恩达深度学习笔记10-Course4-Week1【卷积神经网络】
- C指针原理(40)-递归(1)
- 【时间序列】最完整的时间序列分析和预测(含实例及代码)
- 【深度学习】21个深度学习调参技巧,一定要看到最后一个