SpringBoot+shiro+mybatis实现权限登录,Nginx面试

@SpringBootTestclass CsyApplicationTests {@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {User admin = userMapper.queryUserByUsername(“admin”);System.out.println(admin.toString());Permissions permission = userMapper.queryPermissio
摘要由CSDN通过智能技术生成

@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());

}

}

测试结果:

得到了查询结果

SpringBoot+shiro+mybatis实现权限登录

6.整合Thymeleaf进来:

====================================================================================

前端页面:

在html页面我们整合了Thymeleaf,使用了Jquery,semantic,需要导包

SpringBoot+shiro+mybatis实现权限登录

SpringBoot+shiro+mybatis实现权限登录

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;

/**

  • @MethodName doGetAuthorizationInfo 授权操作

  • @Description 权限配置类

  • @Param [principalCollection]

  • @Return AuthorizationInfo

*/

@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;

}

/**

  • @MethodName doGetAuthenticationInfo 身份验证

  • @Description 认证配置类

  • @Param [authenticationToken]

  • @Return AuthenticationInfo

  • @Author WangShiLin

*/

@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();

}

/**

  • 配置安全管理器 SecurityManager

  • @return

*/

@Bean

public DefaultWebSecurityManager securityManager() {

// 将自定义 Realm 加进来

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

// 关联 Realm

securityManager.setRealm(myShiroRealm());

return securityManager;

}

/**

  • 配置 Shiro 过滤器

  • @param securityManager

  • @return

*/

@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<String, Filter> filterMap = new LinkedHashMap<>();

filterMap.put(“anyRoleFilter”, new MyRolesAuthorizationFilter());

shiroFilterFactoryBean.setFilters(filterMap);

// LinkedHashMap 是有序的,进行顺序拦截器配置

Map<String, String> filterChainMap = new LinkedHashMap<>();

// 配置可以匿名访问的地址,可以根据实际情况自己添加,放行一些静态资源等,anon 表示放行

filterChainMap.put("/css/**", “anon”);

filterChainMap.put("/img/**", “anon”);

filterChainMap.put("/js/**", “anon”);

// 指定页面放行,例如登录页面允许所有人登录

filterChainMap.put("/toLoginPage", “anon”);

// 以“/user/admin” 开头的用户需要身份认证,authc 表示要进行身份认证

filterChainMap.put("/user/admin/**", “authc”);

// 页面 -用户需要角色认证

filterChainMap.put("/levelA/**", “anyRoleFilter[USER,ADMIN,SUPER_ADMIN]”);

filterChainMap.put("/levelB/**", “anyRoleFilter[ADMIN,SUPER_ADMIN]”);

filterChainMap.put("/levelC/**", “anyRoleFilter[SUPER_ADMIN]”);

// filterChainMap.put("/levelA/**", “roles[USER]”);

// filterChainMap.put("/levelB/**", “roles[ADMIN]”);

// filterChainMap.put("/levelC/**", “roles[SUPER_ADMIN]”);

// /user/admin/ 下的所有请求都要经过权限认证,只有权限为 user:[*] 的可以访问,也可以具体设置到 user:xxx

filterChainMap.put("/user/admin/**", “perms[user:*]”);

// 配置注销过滤器

filterChainMap.put("/logout", “logout”);

// 将Map 存入过滤器

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);

return shiroFilterFactoryBean;

}

/**

  • 整合 thymeleaf

  • @return

*/

@Bean(name = “shiroDialect”)

public ShiroDialect shiroDialect(){

return new ShiroDialect();

}

首先我们将自定义的Realm方法,依赖注入进来到容器

//将自己的验证方式加入容器

@Bean

public UserRealm myShiroRealm() {

return new UserRealm();

}

然后是:SecurityManager配置安全管理器

/**

  • 配置安全管理器 Se

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

curityManager

  • @return

*/

@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”;

}

}

UserController:

上面那两个映射,只是测试,主要是那个login方法,他可以根据我们前台输入的数据,并创建一个token,如果该token能被认证,即返回成功页面,否则就失败。

@Controller

public class UserController {

@RequestMapping("/user/queryAll")

@ResponseBody

public String queryAll() {

return “这是 user/queryAll 方法”;

}

@RequestMapping("/user/admin/add")

@ResponseBody

public String adminAdd() {

return “这是 user/adminAdd 方法”;

}

@RequestMapping("/login")

public String login(String username, String password, HttpServletRequest request) {

// 由于是根据name参数获取的,我这里封装了一下

User user = new User();

user.setUsername(username);

user.setPassword(password);

// 创建出一个 Token 内容本质基于前台的用户名和密码(不一定正确)

UsernamePasswordToken token = new UsernamePasswordToken(username, password);

// 获取 subject 认证主体(这里也就是现在登录的用户)

Subject subject = SecurityUtils.getSubject();

try{

// 认证开始,这里会跳转到自定义的 UserRealm 中

subject.login(token);

// 可以存储到 session 中

request.getSession().setAttribute(“user”, user);

return “views/success”;

}catch(Exception e){

// 捕获异常

e.printStackTrace();

request.getSession().setAttribute(“user”, user);

request.setAttribute(“errorMsg”, “兄弟,用户名或密码错误”);

return “views/login”;

}

}

}

8.最终效果:

===========================================================================

首先是 http://localhost :8080/index

SpringBoot+shiro+mybatis实现权限登录

登录界面:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于快速开发Java应用程序的开源框架,Shiro是一个强大且易于使用的Java安全框架,Redis是一个开源的内存数据库。结合使用这些技术可以实现单点登录功能。 在Spring Boot中使用Shiro来处理认证和授权,可以通过配置Shiro的Realm来实现用户的登录认证和权限控制。将用户的信息存储在Redis中,利用Redis的持久化特性来实现用户登录状态的共享和存储。 首先,在Spring Boot项目的配置文件中配置Redis的连接信息,以便连接到Redis数据库。 然后,创建一个自定义的Shiro的Realm,在其中重写认证和授权的方法。在认证方法中,将用户的登录信息存储到Redis中,以便其他服务可以进行验证。在授权方法中,根据用户的角色和权限进行相应的授权操作。 接着,在Spring Boot项目的配置类中配置Shiro的相关设置,包括Realm、Session管理器、Cookie管理器等。 最后,可以在Controller层中使用Shiro的注解来标记需要进行认证和授权的接口,以确保只有登录后且具备相应权限的用户才能访问这些接口。 总的来说,通过使用Spring Boot、Shiro和Redis的组合,可以实现单点登录的功能。用户在登录后,将登录信息存储到Redis中,其他服务可以通过验证Redis中的数据来判断用户的登录状态。同时,Shiro提供了强大的认证和授权功能,可以确保只有具备相应权限的用户才能访问受保护的接口。这些功能的具体实现可以通过深入研究Spring Boot、Shiro和Redis的源码来了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值