SELECt p.* ,r.role_name FROM user u, role r, permission p
WHERe username = #{username} AND u.role_id = r.id AND p.role_id = r.id;
(2)DAO层:
@Mapper
public interface UserMapper {
User queryUserByUsername(@Param(“username”) String username);
Permissions queryPermissionByUsername(@Param(“username”) String username);
}
(3)service层:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User queryUserByUsername(String username) {
return userMapper.queryUserByUsername(username);
}
@Override
public Permissions queryPermissionByUsername(String username) {
return userMapper.queryPermissionByUsername(username);
}
}
弄到这里,我们的mybatis+springboot整合也基本结束,所以在测试类里测试一下:
@SpringBootTest
class CsyApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
User admin = userMapper.queryUserByUsername(“admin”);
System.out.println(admin.toString());
Permissions permission = userMapper.queryPermissionByUsername(“admin”);
System.out.println(permission.toString());
}
}
测试结果:
得到了查询结果
6.整合Thymeleaf进来:
====================================================================================
前端页面:
在html页面我们整合了Thymeleaf,使用了Jquery,semantic,需要导包
index.html代码:
在这里,如果是User就只能访问A,Admin能访问A,B,superAdmin能访问A,B,C
xmlns:th=“http://www.thymeleaf.org”
xmlns=“http://www.w3.org/1999/xhtml”
xmlns:layout=“http://www.ultraq.net.nz/web/thymeleaf/layout”
xmlns:shiro=“http://www.pollix.at/thymeleaf/shiro”
name=“viewport”
content=“width=device-width, initial-scale=1, maximum-scale=1”
/>
href=“https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css”
rel=“stylesheet”
/>
首页
关于
登录
用户名:
注销
L-A-a
L-A-b
L-A-c
L-B-a
L-B-b
L-B-c
L-C-a
L-C-b
L-C-c
晚风吹起你鬓间的白发
抚平回忆留下的疤
你的眼中 明暗交杂 一笑生花
暮色遮住你蹒跚的步伐
走进床头藏起的画
画中的你 低着头说话
我仍感叹于世界之大
也沉醉于儿时情话
不剩真假 不做挣扎 无谓笑话
我终将青春还给了她
连同指尖弹出的盛夏
心之所动 就随风去了
以爱之名 你还愿意吗
❤
理想二旬不止BWH_Steven
login.html代码:
=================================================================================
xmlns=“http://www.w3.org/1999/xhtml”
xmlns:layout=“http://www.ultraq.net.nz/web/thymeleaf/layout”
href=“https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css”
rel=“stylesheet”
/>
用户管理系统-登录登录
success.html:
返回主页
7.将shiro整合到项目里:
===================================================================================
(1)自定义Realm:
================================================================================
我们需要自定义,认证和授权:
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】 浏览器打开:qq.cn.hn/FTf 开源分享
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取用户名信息
String username = (String) principalCollection.getPrimaryPrincipal();
// 创建一个简单授权验证信息
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 给这个用户设置从 role 表获取到的角色信息
authorizationInfo.addRole(userMapper.queryUserByUsername(username).getRole().getRoleName());
//给这个用户设置从 permission 表获取的权限信息
authorizationInfo.addStringPermission(userMapper.queryPermissionByUsername(username).getPermissionName());
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 根据在接受前台数据创建的 Token 获取用户名
String username = (String) authenticationToken.getPrincipal();
// UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
// System.out.println(userToken.getPrincipal());
// System.out.println(userToken.getUsername());
// System.out.println(userToken.getPassword());
// 通过用户名查询相关的用户信息(实体)
User user = userMapper.queryUserByUsername(username);
if (user != null) {
// 存入 Session,可选
SecurityUtils.getSubject().getSession().setAttribute(“user”, user);
// 密码认证的工作,Shiro 来做
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), “userRealm”);
return authenticationInfo;
} else {
// 返回 null 即会抛异常
return null;
}
}
}
(2)写配置类shiroConfig:
=======================================================================================
@Configuration
public class ShiroConfig {
//将自己的验证方式加入容器
@Bean
public UserRealm myShiroRealm() {
return new UserRealm();
}
@Bean
public DefaultWebSecurityManager securityManager() {
// 将自定义 Realm 加进来
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 关联 Realm
securityManager.setRealm(myShiroRealm());
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
// 定义 shiroFactoryBean
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 关联 securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 自定义登录页面,如果登录的时候,就会执行这个请求,即跳转到登录页
shiroFilterFactoryBean.setLoginUrl(“toLoginPage”);
// 指定成功页面
shiroFilterFactoryBean.setSuccessUrl("/success");
// 指定未授权界面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
// 设置自定义 filter
Map
filterMap.put(“anyRoleFilter”, new MyRolesAuthorizationFilter());
shiroFilterFactoryBean.setFilters(filterMap);
// linkedHashMap 是有序的,进行顺序拦截器配置
Map
// 配置可以匿名访问的地址,可以根据实际情况自己添加,放行一些静态资源等,anon 表示放行
filterChainMap.put("/css
@Bean(name = “shiroDialect”)
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
首先我们将自定义的Realm方法,依赖注入进来到容器
//将自己的验证方式加入容器
@Bean
public UserRealm myShiroRealm() {
return new UserRealm();
}
然后是:SecurityManager配置安全管理器
@Bean
public DefaultWebSecurityManager securityManager() {
// 将自定义 Realm 加进来
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 关联 Realm
securityManager.setRealm(myShiroRealm());
return securityManager;
}
最后就是自定义的过滤器,控制那些页面需要什么样的角色才能访问,哪些资源需要谁才能访问,并且setSecurityManager,返回一个ShiroFilterFactoryBean。
重点说一下拦截放行(Map)这块:通过 map 键值对的形式存储,key 存储 URL ,value 存储对应的一些权限或者角色等等,其实 key 这块还是很好理解的,例如 :/css/、/user/admin/ 分别代表 css 文件夹下的所有文件,以及请求路径前缀为 /user/admin/ URL,而对应的 value 就有一定的规范了。
关键:
anon:无需认证,即可访问,也就是游客也可以访问
authc:必须认证,才能访问,也就是例如需要登录后
roles[xxx] :比如拥有某种角色身份才能访问 ,注:xxx为角色参数
perms[xxx]:必须拥有对某个请求、资源的相关权限才能访问,注:xxx为权限参数
(3)自定义一个角色认证过滤器MyRolesAuthorizationFilter:
==============================================================================================================
因为我们的角色,只需用有一个角色就能访问到映射页面,shiro默认是hasAllRoles,也就是说,我们要满足所有的身份才能访问,所以需要我们自定义一个hasAnyRoles,任选其一角色即可。
public class MyRolesAuthorizationFilter extends AuthorizationFilter {
@SuppressWarnings({“unchecked”})
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
Subject subject = getSubject(request, response);
String[] rolesArray = (String[]) mappedValue;
if (rolesArray == null || rolesArray.length == 0) {
//no roles specified, so nothing to check - allow access.
return false;
}
List roles = CollectionUtils.asList(rolesArray);
boolean[] hasRoles = subject.hasRoles(roles);
for (boolean hasRole : hasRoles) {
if (hasRole) {
return true;
}
}
return false;
}
}
(4)最后就是controller
=====================================================================================
controller是springMvc的前端控制器,接收什么请求,并且返回对应指定的页面(映射)。
首先我们先将所以页面的映射写好,
PageController:
@Controller
public class PageController {
@RequestMapping({"/", “index”})
public String index() {
return “index”;
}
@RequestMapping(“about”)
public String toaboutPage() {
return “redirect:http://www.ideal-20.cn”;
}
@RequestMapping("/toLoginPage")
public String toLoginPage() {
return “views/login”;
}
@RequestMapping("/levelA/{name}")
public String toLevelAPage(@PathVariable(“name”) String name) {
return “views/L-A/” + name;
}
@RequestMapping("/levelB/{name}")
public String toLevelBPage(@PathVariable(“name”) String name) {
return “views/L-B/” + name;
}
@RequestMapping("/levelC/{name}")
public String toLevelCPage(@PathVariable(“name”) String name) {
return “views/L-C/” + name;
}
@RequestMapping("/unauthorized")
public String toUnauthorizedPage() {
return “views/unauthorized”;
}
@RequestMapping("/success")
public String toSuccessPage() {
return “views/success”;
}
}



