1.建立一个模块继承上一个模块然后添加依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.8</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.41</version> </dependency> </dependencies> <!--解决打包时找不到xml文件--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
2.建立数据源文件application.properties
#数据库连接相关 jdbc.driver = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/security-demo?useUnicode=true&characterEncoding=utf-8&useSSL=false jdbc.username = root jdbc.password = 123456
3.修改applicationContext.xml,配置数据源,和mybatis整合,以及事务管理
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.alibaba.com/schema/stat" xsi:schemaLocation="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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd"> <!-- 自动扫描 --> <context:component-scan base-package="com.ty"> <!-- 扫描时跳过 @TestController 注解的JAVA类(控制器) --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" /> </context:component-scan> <!--扫描配置文件(这里指向的是之前配置的那个config.properties) --> <context:property-placeholder location="classpath:application.properties" /> <!--配置数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <!--数据库连接驱动 --> <property name="url" value="${jdbc.url}" /> <!--数据库地址 --> <property name="username" value="${jdbc.username}" /> <!--用户名 --> <property name="password" value="${jdbc.password}" /> <!--密码 --> <property name="maxActive" value="40" /> <!--最大连接数 --> <property name="minIdle" value="1" /> <!--最小连接数 --> <property name="initialSize" value="10" /> <!--初始化连接池内的数据库连接 --> <property name="maxWait" value="20" /> <!--最大空闲时间 --> </bean> <!--mybatis与spring整合 --> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--配置别名扫描包--> <property name="typeAliasesPackage" value="com.ty.pojo"></property> <property name="mapperLocations" value="classpath:com.ty.mapper/*.xml"></property> </bean> <!--扫描接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ty.mapper"></property> </bean> <!--事务配置--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!--开启事务--> <tx:annotation-drive ![图片上传中...] n/> </beans>
目录结构,我这里测试mybatis时放在同一包出问题,所以选择了分别扫描xml和mapper接口
数据库,总共建立了5张表,用户表,角色表,用户角色对应表,权限表,权限角色对应表,关系也很简单,一个用户有多个角色,一个角色也可以有多个用户拥有,一个角色有多种权限,一个权限也可以由多个角色掌握,这个看自己怎么设计,其中用户表最重要,这里面包含了用户的基本信息
/* Navicat MySQL Data Transfer Source Server : security Source Server Version : 50719 Source Host : localhost:3306 Source Database : security-demo Target Server Type : MYSQL Target Server Version : 50719 File Encoding : 65001 Date: 2019-08-02 10:25:48 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for sys_authorization -- ---------------------------- DROP TABLE IF EXISTS `sys_authorization`; CREATE TABLE `sys_authorization` ( `id` int(11) NOT NULL, `authorizationName` varchar(50) DEFAULT NULL, `authorizationMark` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_authorization -- ---------------------------- INSERT INTO `sys_authorization` VALUES ('1', '产品查询', 'ROLE_LIST_PRODUCT'); INSERT INTO `sys_authorization` VALUES ('2', '产品添加', 'ROLE_ADD_PRODUCT'); INSERT INTO `sys_authorization` VALUES ('3', '产品修改', 'ROLE_UPDATE_PRODUCT'); INSERT INTO `sys_authorization` VALUES ('4', '产品删除', 'ROLE_DELETE_PRODUCT'); -- ---------------------------- -- Table structure for sys_role -- ---------------------------- DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `id` int(11) NOT NULL, `roleName` varchar(50) DEFAULT NULL, `roleDescription` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_role -- ---------------------------- INSERT INTO `sys_role` VALUES ('1', '普通用户', '普通用户'); INSERT INTO `sys_role` VALUES ('2', '管理员', '管理员'); -- ---------------------------- -- Table structure for sys_role_authorization -- ---------------------------- DROP TABLE IF EXISTS `sys_role_authorization`; CREATE TABLE `sys_role_authorization` ( `roleId` int(11) NOT NULL, `authorizationId` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_role_authorization -- ---------------------------- INSERT INTO `sys_role_authorization` VALUES ('1', '1'); INSERT INTO `sys_role_authorization` VALUES ('1', '2'); INSERT INTO `sys_role_authorization` VALUES ('2', '1'); INSERT INTO `sys_role_authorization` VALUES ('2', '2'); INSERT INTO `sys_role_authorization` VALUES ('2', '3'); INSERT INTO `sys_role_authorization` VALUES ('2', '4'); -- ---------------------------- -- Table structure for sys_user -- ---------------------------- DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL, `password` varchar(100) DEFAULT NULL, `realname` varchar(50) DEFAULT NULL, `createDate` date DEFAULT NULL, `lastLoginTime` date DEFAULT NULL, `enabled` int(11) DEFAULT NULL, `accountNonExpired` int(11) DEFAULT NULL, `accountNonLocked` int(11) DEFAULT NULL, `credentialsNonExpired` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_user -- ---------------------------- INSERT INTO `sys_user` VALUES ('1', 'jojo', '$2a$10$VCvgzml/DNzBTkjsPlImDuZp38sNZB7cEmsNgFIWBm/Vtpn0Q3Bj.', '张三', '2019-06-26', '2019-08-01', '1', '1', '1', '1'); INSERT INTO `sys_user` VALUES ('2', 'jack', '$2a$10$W1T2Z5dUMIgBfxvFdBOWuusq8Nwke/cQydxDFemsbTh0PjGeZCiMC', '李四', '2019-07-30', '2019-08-01', '1', '1', '1', '1'); -- ---------------------------- -- Table structure for sys_user_role -- ---------------------------- DROP TABLE IF EXISTS `sys_user_role`; CREATE TABLE `sys_user_role` ( `userId` int(11) NOT NULL, `roleId` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of sys_user_role -- ---------------------------- INSERT INTO `sys_user_role` VALUES ('1', '1'); INSERT INTO `sys_user_role` VALUES ('2', '2');
基本配置完成
在mapper文件夹下建立UserMapper接口
package com.ty.mapper; import com.ty.pojo.Authorization; import com.ty.pojo.User; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import java.util.List; /** * @Author:TY * @Descroption: * @Date: Created in 11:34 2019/8/1 * @Modificd By: */ public interface UserMapper { @Select("select * from sys_user") List<User> findAll(); /** * 查询当前用户对象 */ public User findByUserName(String username); /** * 查询当前用户的权限 */ List<Authorization> findAuthorizationByUserName(String username); /** * 修改密码 */ @Update("update sys_user set password=#{password} where username=#{username}") public void updatePassword(User user); }
UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ty.mapper.UserMapper"> <select id="findByUserName" resultType="User" parameterType="String"> SELECT * FROM sys_user where username = #{username} </select> <select id="findAuthorizationByUserName" parameterType="String" resultType="Authorization"> SELECT a.* from sys_user u ,sys_user_role ur,sys_role_authorization ra,sys_authorization a WHERE u.id=ur.userId and ur.roleId= ra.roleId and ra.authorizationId=a.id AND u.username=#{username} </select> </mapper>
想要测试就这样
在MainController里面添加一个验证码接口(生成验证码网上都有,这里就不列出了)
@RequestMapping("/imageCode") public void imageCode(HttpServletRequest request, HttpServletResponse response) throws Exception { // ImageCodeProcessor.send(new ServletWebRequest(request,response),new ImageCodeGenerator().generate(new ServletWebRequest(request))); ImageCode generate = new ImageCodeGenerator().generate(new ServletWebRequest(request)); HttpSession session = request.getSession(); System.out.println("生成的验证码为:"+generate.getCode()); session.setAttribute("key",generate.getCode()); response.setContentType("image/jpeg"); // 将图像输出到Servlet输出流中。 ServletOutputStream sos = response.getOutputStream(); ImageIO.write(generate.getImage(), "jpeg", sos); sos.close(); }
pojo包中的User对象,里面添加了一个权限的字段,是user表中没有的,并且User对象实现了UserDetails接口,实现了其中的方法,方便后面security使用
package com.ty.pojo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.util.ArrayList; import java.util.Date; import java.util.List; public class User implements UserDetails{ private Integer id; private String username; private String password; private String realname; private java.util.Date createDate; private java.util.Date lastLoginTime; private boolean enabled; private boolean accountNonExpired; private boolean accountNonLocked; private boolean credentialsNonExpired; //用户拥有的所有权限 List<GrantedAuthority> authorities=new ArrayList<>(); @Override public String toString() { return "User{" + "username='" + username + '/'' + ", realname='" + realname + '/'' + ", authorities=" + authorities + '}'; } @Override public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List<GrantedAuthority> getAuthorities() { return authorities; } public void setAuthorities(List<GrantedAuthority> authorities) { this.authorities = authorities; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getRealname() { return realname; } public void setRealname(String realname) { this.realname = realname; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getLastLoginTime() { return lastLoginTime; } public void setLastLoginTime(Date lastLoginTime) { this.lastLoginTime = lastLoginTime; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean isAccountNonExpired() { return accountNonExpired; } public void setAccountNonExpired(boolean accountNonExpired) { this.accountNonExpired = accountNonExpired; } public boolean isAccountNonLocked() { return accountNonLocked; } public void setAccountNonLocked(boolean accountNonLocked) { this.accountNonLocked = accountNonLocked; } public boolean isCredentialsNonExpired() { return credentialsNonExpired; } public void setCredentialsNonExpired(boolean credentialsNonExpired) { this.credentialsNonExpired = credentialsNonExpired; } }
其它表就直接用idea自带的工具:数据库生成pojo类执行就行了
连接数据库点击
springSecurity.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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd"> <!-- <security:http>:对web.xml中spring过滤器链的配置:web.xml里面的过滤器接受到请求,就会根据这个配置去过滤 1)需要拦截什么资源 2)什么资源什么角色权限 3)定义认证方式:HttpBasic,FormLogin 4)定义登陆页面,定义登陆请求地址,定义错误处理方式 用于授权 --> <security:http> <security:intercept-url pattern="/product/index" access="permitAll()"></security:intercept-url> <security:intercept-url pattern="/product/list" access="hasAuthority('ROLE_LIST_PRODUCT')"></security:intercept-url> <security:intercept-url pattern="/product/add" access="hasAuthority('ROLE_ADD_PRODUCT')"></security:intercept-url> <security:intercept-url pattern="/product/update" access="hasAuthority('ROLE_UPDATE_PRODUCT')"></security:intercept-url> <security:intercept-url pattern="/product/delete" access="hasAuthority('ROLE_DELETE_PRODUCT')"></security:intercept-url> <security:intercept-url pattern="/js/**" access="permitAll()"></security:intercept-url> <security:intercept-url pattern="/imageCode" access="permitAll()"></security:intercept-url> <security:intercept-url pattern="/userLogin" access="permitAll()"></security:intercept-url> <security:intercept-url pattern="/**" access="isFullyAuthenticated()"></security:intercept-url> <!--自定义SpringSecurity过滤器--> <security:custom-filter ref="imageCodeAuthenticationFilter" before="FORM_LOGIN_FILTER"/> <security:form-login login-page="/userLogin" login-processing-url="/login" authentication-success-handler-ref="mySuccessAthenticationHandler" authentication-failure-handler-ref="myAuthenticationFailureHandler"/> <!--权限不足做处理--> <security:access-denied-handler error-page="/error"></security:access-denied-handler> <security:csrf disabled="true"></security:csrf> <!--加上rememberme的功能--> <!--token-validity-seconds:cookie过期时间--> <security:remember-me token-repository-ref="jdbcTokenRepository" token-validity-seconds="3600"></security:remember-me> </security:http> <security:authentication-manager> <security:authentication-provider user-service-ref="myUserDetailService"> <!--使用加密的算法,然后再和数据库密码配对--> <security:password-encoder ref="passwordEncoder"></security:password-encoder> </security:authentication-provider> </security:authentication-manager> <bean id="imageCodeAuthenticationFilter" class="com.ty.security.ImageCodeAuthenticationFilter"> <property name="authenticationFailureHandler" ref="myAuthenticationFailureHandler"></property> </bean> <bean id="myUserDetailService" class="com.ty.security.MyUserDetailService"></bean> <bean id="mySuccessAthenticationHandler" class="com.ty.security.MySuccessAthenticationHandler"></bean> <!--失败处理器--> <bean id="myAuthenticationFailureHandler" class="com.ty.security.MyAuthenticationFailureHandler"></bean> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean> <!--rememberme功能的bean--> <bean id="jdbcTokenRepository" class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl"> <property name="dataSource" ref="dataSource"></property> <!--启动的时候生成表persistent_logins,但是有的话一定要把数据库的表删掉或者把这个注释掉--> <!--<property name="createTableOnStartup" value="true"></property>--> </bean> </beans>
MyUserDetailService :这里就动态在数据库里面动态查询了用户的权限,然后因为之前我们的User类实现了UserDetails接口,所以当返回我们自己从数据库查询的用户然后返回的时候,springSecurity会自己拿着用户输入的信息和我们数据库中的做一个比对,对比上了则认证成功
package com.ty.security; import com.ty.mapper.UserMapper; import com.ty.pojo.Authorization; import com.ty.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import java.util.ArrayList; import java.util.List; /** * @Author:TY * @Descroption: * @Date: Created in 17:09 2019/8/1 * @Modificd By: */ public class MyUserDetailService implements UserDetailsService{ @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user=null; System.out.println(username); if(username!=null&&!username.equals("")) { user = userMapper.findByUserName(username); if (user!=null) { //获取用户权限 List<Authorization> permList = userMapper.findAuthorizationByUserName(username); List<GrantedAuthority> authorizations=new ArrayList<>(); for (Authorization perm:permList) { GrantedAuthority authority=new SimpleGrantedAuthority(perm.getAuthorizationMark()); authorizations.add(authority); } user.setAuthorities(authorizations); } return user; } return user; } }
然后我们自定义成功后的处理器MySuccessAthenticationHandler
package com.ty.security; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @Author:TY * @Descroption: * @Date: Created in 19:43 2019/8/1 * @Modificd By: */ public class MySuccessAthenticationHandler implements AuthenticationSuccessHandler { private static final ObjectMapper objectMapper=new ObjectMapper(); @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { Map map=new HashMap(); map.put("success",true); String result = objectMapper.writeValueAsString(map); httpServletResponse.setContentType("text/json;charset=utf-8"); httpServletResponse.getWriter().write(result); } }
失败处理器:
package com.ty.security; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.security.core.AuthenticationException; 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; import java.util.HashMap; import java.util.Map; /** * @Author:TY * @Descroption: * @Date: Created in 21:23 2019/7/31 * @Modificd By: */ public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler{ private ObjectMapper objectMapper=new ObjectMapper(); @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { Map map=new HashMap(); map.put("success",false); map.put("errorMsg",e.getMessage()); String result = objectMapper.writeValueAsString(map); response.setContentType("text/json;charset=utf-8"); response.getWriter().write(result); } }
登录的时候是先验证验证码,验证码通过在验证用户名和密码
验证码的拦截器
package com.ty.security; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @Author:TY * @Descroption:,他能够确保在一次请求只通过一次filter,而不需要重复执行 * * @Date: Created in 21:22 2019/8/1 * @Modificd By: */ public class ImageCodeAuthenticationFilter extends OncePerRequestFilter { private AuthenticationFailureHandler authenticationFailureHandler; public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) { this.authenticationFailureHandler = authenticationFailureHandler; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //判断当前请求,是否为登录请求, if (request.getRequestURI().contains("/login")) { try { //校验验证码 //表单填的验证码 String imageCode = request.getParameter("imageCode"); System.out.println("表单填的验证码为:"+imageCode); //系统生成的验证码 HttpSession session = request.getSession(); String sesstionCode = (String) session.getAttribute("key"); System.out.println("session里的验证码为:"+sesstionCode); if(imageCode==null||imageCode.equals("")) { throw new ImageCodeException("验证码不能为空"); } if(!imageCode.equals(sesstionCode)) { throw new ImageCodeException("验证码错误"); } }catch (AuthenticationException e){ //交给自定义的 authenticationFailureHandler.onAuthenticationFailure(request,response,e); return; } } filterChain.doFilter(request,response); } }
验证码异常类
package com.ty.security; import org.springframework.security.core.AuthenticationException; /** * @Author:TY * @Descroption: * @Date: Created in 21:47 2019/8/1 * @Modificd By: */ public class ImageCodeException extends AuthenticationException { public ImageCodeException(String msg, Throwable t) { super(msg, t); } public ImageCodeException(String msg) { super(msg); } }
注意:我们是把验证码过滤器加在UserNamePasswordAuthenticationFilter前面的,当我们的验证码抛出异常,验证码没通过时会抛一个ImageCodeException,这个类继承了AuthenticationException ,所以当抛出异常之后会到我们自定义的MyAuthenticationFailureHandler,这样就可以向前端返回异常的数据
login.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: TY Date: 2019/7/31 Time: 19:14 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录页面</title> </head> <body> <c:if test="${not empty param.error}"> <font color="red">用户名或密码错误</font> </c:if> <form id="loginForm"> 用户名:<input type="text" name="username"><br> 密 码:<input type="password" name="password"><br> 验证码:<input type="text" name="imageCode"><img id="imgcheck" src="/imageCode"><br> <input type="checkbox" name="remember-me" value="true">记住我 <input type="button" id="LoginButton" value="登录"> </form> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.min.js"></script> <script type="text/javascript"> $(function () { $("#LoginButton").click(function () { $.post("/login", $("#loginForm").serialize(), function (data) { if (data.success) { window.location.href = "${pageContext.request.contextPath}/product/index"; } else { alert("登录失败:" + data.errorMsg); } }, "json"); }) }) window.onload = function () { var date = new Date(); $("#imgcheck").click(function () { $(this).attr('src', "/imageCode?temp=" + date); }); } </script> </body> </html>
如果要根据权限显示前端内容,就在pom.xml引入
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.3.RELEASE</version> </dependency>
index.jsp
<%-- Created by IntelliJ IDEA. User: TY Date: 2019/7/31 Time: 16:49 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://www.springframework.org/security/tags" prefix="security" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>首页</title> </head> <body> <c:if test="${username != null}"> <span>欢迎${username}登陆</span> </c:if> 以下是网站的功能 <security:authorize access="hasAuthority('ROLE_ADD_PRODUCT')"> <a href="/product/add">商品添加</a> </security:authorize> <security:authorize access="hasAuthority('ROLE_UPDATE_PRODUCT')"> <a href="/product/update">商品修改</a> </security:authorize> <security:authorize access="hasAuthority('ROLE_LIST_PRODUCT')"> <a href="/product/list">商品查询</a> </security:authorize> <security:authorize access="hasAuthority('ROLE_DELETE_PRODUCT')"> <a href="/product/delete">商品删除</a> </security:authorize> </body> </html>
**最后如果想要获取认证通过后的用户的信息,任何地方都能获取
可以使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()
/** * 首页 SecurityContextHolder.getContext().getAuthentication().getPrincipal()可以在任何地方获取当前用户的信息 */ @RequestMapping("index") public String index(Model model) { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if(principal!=null) { if(principal instanceof UserDetails) { UserDetails userDetails= (UserDetails)principal; model.addAttribute("username",userDetails.getUsername()); } } return "index"; }
**