SpringSecurity学习四-自定义Login请求和返回的数据格式

非常感谢https://blog.csdn.net/lee353086/article/details/52610205

SpringSecurity技术学习,更多知识请访问https://www.itkc8.com

环境
 [1]Spring 3.1.2
 [2]Tomcat 7.0.68
 
概要
    完美的解决了《学习三》中自定义login方法得绕过Spring Security部份class的缺陷。
最新的例子,解决以下问题
[1]如果login递交的数据,要求验证“验证码”怎么办。
[2]若访问页面没有权限,返回json形式的错误提示。
[3]若login递交的数据非法,返回json形式的错误提示。
[4]若login递交的数据合法,返回json形式的提示。
[5]同个帐号只能同时一次有效,若异地已经登录了这个帐号,会自动把它踢掉。
[6]如何查看登录到Web App的所有用户信息。


也能解决
[1]若已经在其它地方登录的帐户,可以提个醒,你已经把其它地方登录的这个帐号踢掉了。
通过修改MyAuthenticationFilter.java。
[2]若你已经在其它地方登录,不允许再登录。
通过修改spring-security.xml。

   正文中会介绍下主要类的功能,然后直接上代码。
   《学习二》中未动的代码,这里不重复贴了。

   本文的例子在Chrome和Firefox下测试通过。

  理解整个Demo建议从spring-security.xml文件开始。

 

正文
相对于《学习二》这里最重要的是五个java文件,一个配置文件,必须要深刻理解它们之间的关系和功能。

MyAuthenticationEntryPoint.java
当用户没有权限访问某个资源的时候,你可以在这里自定义返回内容。

MyAuthenticationFilter.java
自定义login请求的格式,比如你想上传json格式的请求,可以在这里处理。
并验证用户的请求是否合法,如果不合法你可以抛出继承自AuthenticationException的Exception

MyAuthenticationException.java
继承AuthenticationException,在MyAuthenticationFilter中抛出后,交给MyAuthenticationFailureHandler处理

MyAuthenticationFailureHandler.java
当login失败,这里可以自定义返回的错误信息。

MyAuthenticationSuccessHandler.java
如何登录成功,这里可以自定义返回的成功信息。

配置文件
web.xml

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  3. xmlns="http://java.sun.com/xml/ns/javaee"

  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

  5. id="schedule-console" version="3.0">

  6. <display-name>Archetype Created Web Application</display-name>

  7.  
  8. <!-- 配置字符集过滤器 -->

  9. <!-- 必须配置在所有过滤器的前面 -->

  10. <filter>

  11. <filter-name>encodingFilter</filter-name>

  12. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

  13. <init-param>

  14. <param-name>encoding</param-name>

  15. <param-value>UTF-8</param-value>

  16. </init-param>

  17. </filter>

  18.  
  19. <!-- 配置项目的编码mapping -->

  20. <filter-mapping>

  21. <filter-name>encodingFilter</filter-name>

  22. <url-pattern>/*</url-pattern>

  23. </filter-mapping>

  24.  
  25. <!-- 如果同一个bean被定义两次,后面一个优先 -->

  26. <context-param>

  27. <param-name>contextConfigLocation</param-name>

  28. <param-value>/WEB-INF/spring-servlet.xml,/WEB-INF/spring-security.xml</param-value>

  29. </context-param>

  30.  
  31. <!-- 启动spring容器用,容器用于管理Bean -->

  32. <listener>

  33. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  34. </listener>

  35.  
  36. <!-- Spring Security会话控制 -->

  37. <listener>

  38. <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

  39. </listener>

  40.  
  41. <!-- Spring security Filter -->

  42. <filter>

  43. <filter-name>springSecurityFilterChain</filter-name>

  44. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

  45. </filter>

  46.  
  47. <filter-mapping>

  48. <filter-name>springSecurityFilterChain</filter-name>

  49. <url-pattern>/*</url-pattern>

  50. </filter-mapping>

  51.  
  52. <!-- DispatcherServlet 针对MVC上下文加载,即拦截请求,分发请求给Controller -->

  53. <!-- 《ContextLoaderListener初始化的前后文和DispatcherServlet初始化的上下文关系》 http://www.educity.cn/wenda/356953.html -->

  54. <servlet>

  55. <servlet-name>spring</servlet-name>

  56. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

  57. <load-on-startup>1</load-on-startup>

  58. </servlet>

  59.  
  60. <!-- url-pattern配置为/,不带文件后缀,会造成其它静态文件(js,css等)不能访问。如配为*.do,则不影响静态文件的访问 -->

  61. <servlet-mapping>

  62. <servlet-name>spring</servlet-name>

  63. <url-pattern>*.do</url-pattern>

  64. </servlet-mapping>

  65.  
  66. <welcome-file-list>

  67. <welcome-file>index.jsp</welcome-file>

  68. </welcome-file-list>

  69.  
  70. <error-page>

  71. <error-code>404</error-code>

  72. <location>/My404.jsp</location>

  73. </error-page>

  74.  
  75. <error-page>

  76. <exception-type>java.lang.Exception</exception-type>

  77. <location>/MyEception.jsp</location>

  78. </error-page>

  79. </web-app>



spring-security.xml

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <b:beans xmlns="http://www.springframework.org/schema/security"

  3. xmlns:b="http://www.springframework.org/schema/beans"

  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

  6. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

  7.  
  8. <http pattern="/main/customLogin.do" security="none" />

  9.  
  10. <http access-denied-page="/accessDenied.jsp"

  11. entry-point-ref="authenticationEntryPoint">

  12. <logout logout-url="/j_spring_security_logout"

  13. logout-success-url="/main/customLogin.do"

  14. invalidate-session="true" />

  15.  
  16. <intercept-url pattern="/main/welcome.do" access="ROLE_ADMIN" />

  17.  
  18. <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>

  19.  
  20. <!-- 这里添加自己定义的AuthenticationFilter到FilterChain的FORM_LOGIN_FILTER位置 -->

  21. <!-- 所以上面不需要定义form-login属性了 -->

  22. <custom-filter ref="myAuthenticationFilter" position="FORM_LOGIN_FILTER"/>

  23. <custom-filter ref="concurrencyFilter" position="CONCURRENT_SESSION_FILTER" />

  24.  
  25. <session-management session-authentication-strategy-ref="sessionAuthenticationStrategy">

  26. </session-management>

  27. </http>

  28.  
  29. <b:bean id="concurrencyFilter"

  30. class="org.springframework.security.web.session.ConcurrentSessionFilter">

  31. <b:property name="sessionRegistry" ref="sessionRegistry" />

  32. <b:property name="expiredUrl" value="/sessionExpired.jsp" />

  33. </b:bean>

  34.  
  35. <!-- 在MyAuthenticationFilter中可以自定义数据的请求格式 -->

  36. <b:bean id="myAuthenticationFilter"

  37. class="com.nuoke.MyAuthenticationFilter">

  38. <b:property name="authenticationManager" ref="authenticationManager" />

  39. <b:property name="sessionAuthenticationStrategy" ref="sessionAuthenticationStrategy" />

  40. <b:property name="usernameParameter" value="username"/>

  41. <b:property name="passwordParameter" value="password"/>

  42. <b:property name="filterProcessesUrl" value="/main/customLogin2.do" />

  43. <b:property name="authenticationSuccessHandler">

  44. <b:bean class="com.nuoke.MyAuthenticationSuccessHandler">

  45. <!-- 不能设置/WEB-INF下的jsp,会访问不到,虽然服务端Console不会打印错误信息 -->

  46. <!-- 但是客户端也不会收到你指定的jsp信息 -->

  47. <b:property name="defaultTargetUrl" value="/customLoginResponse.jsp"></b:property>

  48. </b:bean>

  49. </b:property>

  50. <b:property name="authenticationFailureHandler">

  51. <b:bean class="com.nuoke.MyAuthenticationFailureHandler">

  52. <!-- 不能设置/WEB-INF下的jsp,会访问不到,虽然服务端Console不会打印错误信息 -->

  53. <!-- 但是客户端也不会收到你指定的jsp信息 -->

  54. <b:property name="defaultFailureUrl" value="/customLoginResponse.jsp"></b:property>

  55. </b:bean>

  56. </b:property>

  57. </b:bean>

  58.  
  59. <!-- 若访问没有权限,自动跳到下面指定的页面 -->

  60. <b:bean id="authenticationEntryPoint" class="com.nuoke.MyAuthenticationEntryPoint">

  61. <b:property name="loginFormUrl" value="/main/customLogin.do" />

  62. </b:bean>

  63.  
  64. <!--一个自定义的filter,必须包含 authenticationManager,accessDecisionManager,securityMetadataSource三个属性,

  65. 我们的所有控制将在这三个类中实现,解释详见具体配置 -->

  66. <b:bean id="myFilter"

  67. class="com.nuoke.MyFilterSecurityInterceptor">

  68. <b:property name="authenticationManager" ref="authenticationManager" />

  69. <b:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" />

  70. <b:property name="securityMetadataSource" ref="securityMetadataSource" />

  71. </b:bean>

  72.  
  73. <!--验证配置,认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->

  74. <authentication-manager alias="authenticationManager">

  75. <authentication-provider user-service-ref="myUserDetailService">

  76. <!--如果用户的密码采用加密的话 -->

  77. <password-encoder hash="md5"/>

  78. </authentication-provider>

  79. </authentication-manager>

  80.  
  81. <!--在这个类中,你就可以从数据库中读入用户的密码,角色信息,是否锁定,账号是否过期等 -->

  82. <b:bean id="myUserDetailService" class="com.nuoke.MyUserDetailService" />

  83.  
  84. <!--访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->

  85. <b:bean id="myAccessDecisionManagerBean"

  86. class="com.nuoke.MyAccessDecisionManager">

  87. </b:bean>

  88.  
  89. <b:bean id="sessionAuthenticationStrategy"

  90. class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">

  91. <b:constructor-arg name="sessionRegistry" ref="sessionRegistry" />

  92. <b:property name="maximumSessions" value="1" />

  93. <b:property name="exceptionIfMaximumExceeded" value="false" />

  94. </b:bean>

  95. <b:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

  96.  
  97. <!--资源数据定义,将所有的资源和权限对应关系建立起来,即定义某一资源可以被哪些角色访问 -->

  98. <b:bean id="securityMetadataSource"

  99. class="com.nuoke.MyInvocationSecurityMetadataSource" />

  100. </b:beans>


 

java文件

MyAuthenticationEntryPoint.java

 
  1. package com.nuoke;

  2.  
  3. import java.io.IOException;

  4.  
  5. import javax.servlet.ServletException;

  6. import javax.servlet.http.HttpServletRequest;

  7. import javax.servlet.http.HttpServletResponse;

  8.  
  9. import org.springframework.security.core.AuthenticationException;

  10. import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

  11.  
  12. public class MyAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint{

  13. //当访问的资源没有权限,会调用这里

  14. @Override

  15. public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)

  16. throws IOException, ServletException {

  17. //super.commence(request, response, authException);

  18.  
  19. //返回json形式的错误信息

  20. response.setCharacterEncoding("UTF-8");

  21. response.setContentType("application/json");

  22.  
  23. response.getWriter().println("{\"ok\":0,\"msg\":\""+authException.getLocalizedMessage()+"\"}");

  24. response.getWriter().flush();

  25. }

  26. }


MyAuthenticationException.java

 
  1. package com.nuoke;

  2.  
  3. import org.springframework.security.core.AuthenticationException;

  4.  
  5. public class MyAuthenticationException extends AuthenticationException {

  6.  
  7. /**

  8. *

  9. */

  10. private static final long serialVersionUID = 1L;

  11.  
  12. public MyAuthenticationException(String msg) {

  13. super(msg);

  14. // TODO Auto-generated constructor stub

  15. }

  16.  
  17. }


MyAuthenticationFailureHandler.java

 
  1. package com.nuoke;

  2.  
  3. import java.io.IOException;

  4.  
  5. import javax.servlet.ServletException;

  6. import javax.servlet.http.HttpServletRequest;

  7. import javax.servlet.http.HttpServletResponse;

  8. import javax.servlet.http.HttpSession;

  9.  
  10. import org.springframework.security.core.AuthenticationException;

  11. import org.springframework.security.web.WebAttributes;

  12. import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

  13.  
  14. public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler{

  15. @Override

  16. public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,

  17. AuthenticationException exception) throws IOException, ServletException {

  18. // Example1(request,response,exception);

  19. // Example2(request,response,exception);

  20. Example3(request,response,exception);

  21. }

  22.  
  23. private void Example1(HttpServletRequest request, HttpServletResponse response,

  24. AuthenticationException exception) throws IOException, ServletException

  25. {

  26. //例1:直接返回字符串

  27. response.setCharacterEncoding("UTF-8");

  28. response.setContentType("application/json");

  29.  
  30. response.getWriter().println("{\"ok\":0,\"msg\":\""+exception.getLocalizedMessage()+"\"}");

  31. }

  32.  
  33. private void Example2(HttpServletRequest request, HttpServletResponse response,

  34. AuthenticationException exception) throws IOException, ServletException

  35. {

  36. String strUrl = request.getContextPath() + "/customLoginResponse.jsp";

  37. request.getSession().setAttribute("ok", 0);

  38. request.getSession().setAttribute("message", exception.getLocalizedMessage());

  39. request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);

  40. super.onAuthenticationFailure(request, response, exception);

  41. }

  42.  
  43. private void Example3(HttpServletRequest request, HttpServletResponse response,

  44. AuthenticationException exception) throws IOException, ServletException

  45. {

  46. //例3:自定义跳转到哪个URL

  47. //假设login.jsp在webapp路径下

  48. //注意:不能访问WEB-INF下的jsp。

  49. String strUrl = request.getContextPath() + "/customLoginResponse.jsp";

  50. request.getSession().setAttribute("ok", 0);

  51. request.getSession().setAttribute("message", exception.getLocalizedMessage());

  52. request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);

  53. //Error request.getRequestDispatcher(strUrl).forward(request, response);

  54. response.sendRedirect(strUrl);

  55. }

  56. }


MyAuthenticationFilter.java

 
  1. package com.nuoke;

  2.  
  3. import java.util.Enumeration;

  4.  
  5. import javax.servlet.http.HttpServletRequest;

  6. import javax.servlet.http.HttpServletResponse;

  7. import javax.servlet.http.HttpSession;

  8.  
  9. import org.springframework.security.core.Authentication;

  10. import org.springframework.security.core.AuthenticationException;

  11. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

  12.  
  13. /*

  14. * 说明:

  15. * UsernamePasswordAuthenticationFilter用于处理来自表单提交的认证。该表单必须提供对应的用户名和密码,

  16. * 对应的参数名默认为j_username和j_password。

  17. * 如果不想使用默认的参数名,可以通过UsernamePasswordAuthenticationFilter的usernameParameter和passwordParameter进行指定。

  18. * 表单的提交路径默认是“j_spring_security_check”,可以通过UsernamePasswordAuthenticationFilter的filterProcessesUrl进行指定。

  19. * 通过属性postOnly可以指定只允许登录表单进行post请求,默认是true。

  20. */

  21.  
  22. public class MyAuthenticationFilter extends UsernamePasswordAuthenticationFilter{

  23. public Authentication attemptAuthentication(HttpServletRequest request,

  24. HttpServletResponse response) throws AuthenticationException {

  25. //这里可以抛出继承自AuthenticationException的exception

  26. //然后会转到MyAuthenticationFailureHandler。

  27. //比如说验证码什么的可以在这里验证,然后抛出异常。

  28. //然后让MyAuthenticationFailureHandler去处理,并输出返回

  29.  
  30. //下面的代码段是具体的示例

  31. //当用户输入的用户名为“123”抛出自定义的AuthenticationException异常。

  32. String username = request.getParameter("username");

  33. if(username.equals("123"))

  34. {

  35. throw new MyAuthenticationException("测试异常被MyAuthenticationFailureHandler处理");

  36.  
  37. }

  38.  
  39. return super.attemptAuthentication(request, response);

  40. }

  41. }


MyAuthenticationSuccessHandler.java

 
  1. package com.nuoke;

  2.  
  3. import java.io.IOException;

  4.  
  5. import javax.servlet.ServletException;

  6. import javax.servlet.http.HttpServletRequest;

  7. import javax.servlet.http.HttpServletResponse;

  8.  
  9. import org.springframework.security.core.Authentication;

  10. import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

  11.  
  12.  
  13. public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{

  14. @Override

  15. public void onAuthenticationSuccess(HttpServletRequest request,

  16. HttpServletResponse response,

  17. Authentication authentication) throws ServletException, IOException

  18. {

  19. //例1:不跳到XML设定的页面,而是直接返回json字符串

  20. response.setCharacterEncoding("UTF-8");

  21. response.setContentType("application/json");

  22.  
  23. response.getWriter().println("{\"ok\":\"1\",\"msg\":\"登录成功\"}");

  24.  
  25. //例2:跳转到XML中设定的URL。其实已经没有定义这个class的意义

  26. //super.onAuthenticationSuccess(request, response, authentication);

  27.  
  28. //例3:自定义跳转到哪个URL

  29. //http://cl315917525.iteye.com/blog/1768396

  30. }

  31. }


MyController.java

 
  1. package com.nuoke.controller;

  2.  
  3. import java.util.ArrayList;

  4. import java.util.List;

  5.  
  6. import javax.servlet.http.HttpServletRequest;

  7. import javax.servlet.http.HttpSession;

  8.  
  9. import org.springframework.beans.factory.annotation.Autowired;

  10. import org.springframework.beans.factory.annotation.Qualifier;

  11. import org.springframework.security.authentication.AuthenticationManager;

  12. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

  13. import org.springframework.security.core.Authentication;

  14. import org.springframework.security.core.AuthenticationException;

  15. import org.springframework.security.core.context.SecurityContextHolder;

  16. import org.springframework.security.core.session.SessionRegistry;

  17. import org.springframework.security.core.userdetails.User;

  18. import org.springframework.stereotype.Controller;

  19. import org.springframework.web.bind.annotation.RequestMapping;

  20. import org.springframework.web.bind.annotation.RequestParam;

  21. import org.springframework.web.servlet.ModelAndView;

  22.  
  23. @Controller

  24. @RequestMapping(value = "/main")

  25. public class MyController {

  26. @Autowired

  27. @Qualifier("sessionRegistry")

  28. private SessionRegistry sessionRegistry;

  29.  
  30. @RequestMapping(value = "/admin.do")

  31. public ModelAndView adminPage() {

  32. ModelAndView model = new ModelAndView();

  33. model.addObject("title", "Spring Security Hello World");

  34. model.addObject("message", "这是一个安全被保护的页面!");

  35. //在MyInvocationSecurityMetadataSource类中指定了保护。

  36. model.setViewName("admin");

  37.  
  38. return model;

  39. }

  40.  
  41. @RequestMapping(value = "/welcome.do")

  42. public ModelAndView WelcomeAction() {

  43. this.PrintAllOnlineUser();

  44. ModelAndView model = new ModelAndView();

  45. model.addObject("title", "Spring Security Hello World");

  46. model.addObject("message", "这是一个欢迎页面!");

  47. model.setViewName("welcome");

  48. return model;

  49. }

  50.  
  51. //打印在线用户

  52. void PrintAllOnlineUser()

  53. {

  54. List<Object> principals = sessionRegistry.getAllPrincipals();

  55.  
  56. List<String> usersNamesList = new ArrayList<String>();

  57.  
  58. for (Object principal: principals) {

  59. if (principal instanceof User) {

  60. usersNamesList.add(((User) principal).getUsername());

  61. }

  62. }

  63.  
  64. System.out.println("count:"+usersNamesList.size()+"=>"+usersNamesList.toString());

  65. }

  66.  
  67. @RequestMapping(value="/customLogin.do")

  68. public String customLoginAction(HttpServletRequest request){

  69. return "customLogin";

  70. }

  71. }//end class



jsp文件
webapp目录下的

customLoginResponse.jsp

 
  1. <%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

  3. {"ok":${sessionScope.ok},"msg":"${sessionScope.message}","SPRING_SECURITY_LAST_EXCEPTION":"${sessionScope.SPRING_SECURITY_LAST_EXCEPTION}"}


MyException.jsp

 
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>

  2. <%

  3. Exception ex = (Exception) request.getAttribute("Exception");

  4. String strMsg = "未知错误";

  5. if(ex!=null)

  6. strMsg = ex.getMessage();

  7. %>

  8. {"ok":"0","msg":"<%=strMsg%>"}


sessionExpired.jsp

 
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

  2. <%

  3. String path = request.getContextPath();

  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

  5. %>

  6. {"ok":0,"msg":"你已经在其它地方登录!"}


My404.jsp

 
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"

  2. pageEncoding="UTF-8"%>

  3. {"ok":0,"msg":"404错误"}


WEB-INF/view目录下的

customLogin.jsp

 
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

  3. <html>

  4. <head>

  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

  6. <title>自定义登录控制</title>

  7.  
  8. <link href="../common/bootstrap/css/bootstrap.min.css" rel="stylesheet">

  9. <link href="../common/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet">

  10.  
  11. <script type="text/javascript"

  12. src="../common/bootstrap/js/bootstrap.min.js"></script>

  13. <script type="text/javascript"

  14. src="../common/jquery/jquery-2.1.1.min.js"></script>

  15. <body>

  16. <div class="container">

  17. <div id="container_demo">

  18. <div id="wrapper">

  19. <div id="login" class="animate form">

  20. <h1>示例二 自定义login方法</h1>

  21. <form id='loginForm' method="POST">

  22. <p>

  23. <label for="" class="uname" data-icon="u"> 用户名 </label>

  24. <input id="username" name="username" required="required" type="text" placeholder="myusername or mymail@mail.com">

  25. </p>

  26. <p>

  27. <label for="" class="youpasswd" data-icon="p"> 密码 </label>

  28. <input id="password" name="password" required="required" type="password" placeholder="eg. X8df!90EO">

  29. </p>

  30. <p class="login button">

  31. <input type="submit" id="submitId" value="登录">

  32. </p>

  33. </form>

  34. </div>

  35. </div>

  36. </div>

  37. </div>

  38. </body>

  39.  
  40. <script type="text/javascript">

  41. $(function(){

  42. /登录提交

  43. $("#loginForm").submit(function() {

  44. var username=$("#username").val();

  45. var password=$("#password").val();

  46. var data={username:username,password:password};

  47. var url="/testSpringSecurity2/main/customLogin2.do";

  48. $.ajax({

  49. type: "POST",

  50. url: url,

  51. data: data,

  52. // contentType: "application/json",

  53. dataType: "json",

  54. success:function (result) {

  55. if(result.ok){

  56. location.href="/testSpringSecurity2/main/admin.do";

  57. } else

  58. {

  59. alert(">>"+result.SPRING_SECURITY_LAST_EXCEPTION)

  60. $(".error").remove();

  61. $("#loginForm").prepend("<div class='error'><font color='red'>"+result.msg+"</font></div>");

  62. }

  63. },

  64. error:function(XMLHttpRequest, textStatus, errorThrown){

  65. alert('读取超时,请检查网络连接...');

  66. }

  67. });

  68. return false;

  69. });

  70. });

  71. </script>

  72. </html>


 


总结
   太庞大复杂,不敢用在现有的项目当中,怕又出现新的坑,打算以后新的项目中尝试Spring Security框架。

 

常见问题

Q MyAuthenticationFilter不会被调用的问题

如果你使用了类似下面的语句

<http pattern="/public/**"   security="none"/>

排除哪些url  pattern spring security不检查权限,

则指定login路径的时候不能在public路径下,如下,下面用main代替了public:

<beans:bean id="myAuthenticationFilter"   ...      ...

<beans:property name="filterProcessesUrl" value="/main/login.do" />

问题解决。

SpringSecurity技术学习,更多知识请访问https://www.itkc8.com
   
参考资料
[1]《Spring Security and JSON Authentication》
继承UsernamePasswordAuthenticationFilter实现json形式的登录
http://stackoverflow.com/questions/19500332/spring-security-and-json-authentication
[2]失败返回json字符串
http://blog.csdn.net/jmppok/article/details/44832641

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringSecurity提供了自定义AuthenticationProvider和AuthenticationFilter的功能。在Spring Security中,AuthenticationProvider是一个接口,用于对用户进行身份验证。默认的实现是DaoAuthenticationProvider。你可以通过实现该接口来创建自定义的身份验证提供者,以适应特定的需求。自定义的AuthenticationProvider可以通过在配置文件中指定来替换默认的Provider。例如,在配置文件中添加以下代码可以引用自定义的Provider: ```xml <authentication-manager> <authentication-provider ref="customProvider" /> </authentication-manager> ``` 此处的`customProvider`是指自定义的AuthenticationProvider的bean的ID,你可以根据实际情况进行修改。 另外,AuthenticationFilter是用于处理身份验证请求的过滤器。它负责从请求中提取用户凭证并使用AuthenticationProvider进行身份验证。Spring Security提供了多个不同类型的AuthenticationFilter,如UsernamePasswordAuthenticationFilter、BasicAuthenticationFilter等。你可以根据需要选择合适的AuthenticationFilter,并将其配置到Spring Security的过滤器链中。 关于Spring Security的源码,你可以在GitHub上找到它的源码存储库。在这个存储库中,你可以查看和学习Spring Security的实现细节。 总结起来,你可以通过自定义AuthenticationProvider来实现特定需求的身份验证,同时可以选择合适的AuthenticationFilter来处理身份验证请求。你可以参考Spring Security的源码来了解更多细节和实现方式。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [SpringSecurity自定义AuthenticationProvider和AuthenticationFilter](https://blog.csdn.net/weixin_34248849/article/details/93984642)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Spring Security笔记:自定义Login/Logout Filter、AuthenticationProvider、AuthenticationToken](https://blog.csdn.net/weixin_33907511/article/details/85647330)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值