让不同权限的用户通过登录进入到一个页面,页面相应的显示不同的模块的功能
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--模板--> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> <version>3.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> <!-- subject用户 securityManager管理所有的用户 Realm 连接数据 --> <!-- 整合包shiro-spring--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.1</version> </dependency> <!-- 日志--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- 德鲁伊 mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.6</version> </dependency> <!-- mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!-- lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <!--shiro和thymeleaf--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
application.properties
#绑定mybatis
mybatis.type-aliases-package=com.wu.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
server.port=8081
application.yml
spring: datasource: username: root password: root url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.jdbc.Driver #配置德鲁伊,后续可以配置德鲁伊相关的东西 type: com.alibaba.druid.pool.DruidDataSource #SpringBoot默认是不注入这些的,需要自己绑定 #druid数据源专有配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入 #如果允许报错,java.lang.ClassNotFoundException: org.apache.Log4j.Properity #则导入log4j 依赖就行 filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
User/add和User/update没什么好说的
index.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http:www.thymeleaf.org/thymeleaf-extras-shiro"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>首页</h1> <!--如果已经登录就不显示登录--> <div th:if="${session.loginUser}==null"> <a th:href="@{/toLogin}">登录</a></div> <p th:text="${msg}"></p> <hr> <div shiro:hasPermission="user:add"> <a th:href="@{/user/add}">add</a> </div> <div shiro:hasPermission="user:update"> <a th:href="@{/user/update}">update</a> </div> </body> </html>
login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 登陆 <p th:text="${msg}" style="color: red;"></p> <form th:action="@{/login}"> <p>用户名:<input type="text" name="username"></p> <p>密码:<input type="text" name="password"></p> <p><input type="submit"></p> </form> </body> </html>
@Data @NoArgsConstructor @AllArgsConstructor public class User { private int id; private String name; private String pwd; private String perms; }
接口
@Repository @Mapper public interface UserMapper { User queryUserByName(String name); }
对应的Mapper.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.wu.mapper.UserMapper"> <select id="queryUserByName" parameterType="String" resultType="User" > select * from mybatis.user where name = #{name} </select> </mapper>
接口
public interface UserService { User queryUserByName(String name); }
实现类
@Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public User queryUserByName(String name) { return userMapper.queryUserByName(name); } }
@Controller public class MyController { @RequestMapping({"/","/index"}) public String toIndex(Model model){ model.addAttribute("msg","hello,Shiro"); return "index"; } @RequestMapping("/user/add") public String add(){ return "User/add"; } @RequestMapping("/user/update") public String update(){ return "User/update"; } @RequestMapping("/toLogin") public String toLogin(){ return "login"; } @RequestMapping("/login") public String login(String username,String password,Model model){ //获取当前的用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登陆数据 UsernamePasswordToken token = new UsernamePasswordToken(username,password); try { subject.login(token);//执行登陆的方法,如果没有异常就ok return "index"; } catch (UnknownAccountException e) { model.addAttribute("msg","用户名错误"); return "login"; }catch (IncorrectCredentialsException e) { model.addAttribute("msg","密码不存在"); return "login"; } } //未授权 @ResponseBody @RequestMapping("/noauth") public String unauthorized(){ return "未经授权无法访问此页面"; } }
ShiroConfig
@Configuration public class ShiroConfig { //3.ShiroFilterFactoryBean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager ){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); /* anno:无需认证就可以访问 authc:必须认证了才能访问 user:必须拥有记住我功能才能用 perms:拥有对某个资源的权限才能访问 role:拥有某个角色权限才能访问 */ Map<String,String> filterMap=new LinkedHashMap<>(); filterMap.put("/user/add","perms[user:add]");//有add权限才能访问 filterMap.put("/user/update","perms[user:update]"); bean.setFilterChainDefinitionMap(filterMap); //设置拦截成功后跳到登陆页面 bean.setLoginUrl("/toLogin"); //未授权的页面 bean.setUnauthorizedUrl("/noauth"); return bean; } //2.DefaultWebSecurityManager @Bean(name="securityManager") public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){//绑定下方的类 DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager(); //关联UserRealm webSecurityManager.setRealm(userRealm); return webSecurityManager; } //1.创建realm对象 需要自定义类 @Bean(name="userRealm") public UserRealm userRealm(){ return new UserRealm(); } //整合shiro和thymeleaf @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
UserRealm自定义类
public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //拿到用户的对象 Subject subject = SecurityUtils.getSubject(); User currentUser = (User)subject.getPrincipal();//拿到user对象 //设置当前用户的权限 info.addStringPermission(currentUser.getPerms()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) authenticationToken; //连接真实的数据库 User user = userService.queryUserByName(usernamePasswordToken.getUsername()); if(user==null){ //查无此人 return null;//自动报没有用户名的异常 } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("loginUser",user); //从这里把认证的用户作为数据传递给授权 return new SimpleAuthenticationInfo(user,user.getPwd(),""); } }
测试数据库连接成功的测试类
@SpringBootTest class DemoApplicationTests { @Autowired UserServiceImpl userService; @Test void contextLoads() { System.out.println(userService.queryUserByName("xixi")); } }
一些spring注解的相关内容
https://blog.csdn.net/u010648555/article/details/76299467?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162442572216780262563579%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162442572216780262563579&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-76299467.pc_search_result_before_js&utm_term=spring%E6%B3%A8%E8%A7%A3&spm=1018.2226.3001.4187
原文:https://www.cnblogs.com/wuyimin/p/14922291.html