shiro进行登录认证和授权

您所在的位置:网站首页 shiro权限控制的方式 shiro进行登录认证和授权

shiro进行登录认证和授权

2023-11-18 00:28| 来源: 网络整理| 查看: 265

1.Shiro核心架构ababab 三个常用过滤器

anno:不需要任何权限即可访问资源 authc:需要登录的权限才可以访问资源 perms:需要指定的权限才能访问目标资源

2.shiro登录认证

使用认证过滤器 1.在shiro的xml文件中添加认证过滤器,创建shiroFilterFactoryBean,创建securityManager对象,创建自定义的realm 例:

/css/**=anon /img/**=anon /make/**=anon /plugins/**=anon /login.do=anon /**=authc

控制层的登录认证 1.得到subject对象,将账号(邮箱)密码封装到token,发出登录请求登录成功得到一个登录成功对象 例:

@Controller public class LoginController extends BaseController { @Autowired private UserService userService; @Autowired private ModuleService moduleService; /* url: /login.do 作用:校验登陆 参数:email(邮箱) ,password(密码) 返回值: 登陆成功 home/main(后台首页) || 登陆失败: login.jsp() */ @RequestMapping("/login") public String login(String email,String password){ //1. 判断用户名与密码是否为空,如果两者有一者为空都是回到登陆页面 if(StringUtils.isEmpty(email)||StringUtils.isEmpty(password)){ request.setAttribute("error","用户名或者密码不能为空"); //注意: login.jsp不在pages目录中,所以不要经过视图解析器,所以前面带上forward或者redirect return "forward:/login.jsp"; } try { //2. 得到subject的对象 Subject subject = SecurityUtils.getSubject(); //3. 把邮箱与密码封装到Token里面 UsernamePasswordToken token = new UsernamePasswordToken(email,password); //4. 使用subject发出登陆的请求,携带token过去, 这里的登录方法本质上是会调用realm里面的登陆方法 subject.login(token); //5. 登陆成功得到一个登陆成功的对象, shiro登陆成功之后其实shiro本质上也会在session中做很多登陆成功标记 User loginUser = (User) subject.getPrincipal(); //这里做的不是登录成功标记,而且我们页面上需要使用登陆者的信息,所以我们保存登陆者的信息 session.setAttribute("loginUser",loginUser); //6. 查看该登陆成功的用户的权限 List moduleList = moduleService.findModuleByUser(loginUser); session.setAttribute("modules",moduleList); //返回到后台的首页 return "home/main"; } catch (UnknownAccountException e) { //如果一旦出现了该异常,代表不存在用户名 request.setAttribute("error","用户名或者密码错误"); return "forward:/login.jsp"; }catch (IncorrectCredentialsException e){ //密码错误的异常 request.setAttribute("error","用户名或者密码错误"); return "forward:/login.jsp"; } } }

编写AuthRealm,实现登录认证 根据token转为用户名、密码,根据用户名查找用户,存在用户则对比密码 例:

public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; //登录认证方法 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //1. 先把token强制UsernamePasswordToken UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; //2. 得到邮箱与密码 String email = usernamePasswordToken.getUsername(); // String password = new String(usernamePasswordToken.getPassword()); //用户输入的密码 //3. 根据邮箱去数据库查找一个用户 User dbUser = userService.findByEmail(email); //4. 如果查找到的用户等于null,代表用户名不存在,直接返回null即可。当你返回null的时候,subject.login方法会接收到一个异常 if(dbUser==null){ return null; } //5. 如果用户存在,那么则通知shiro去对比密码 /* SimpleAuthenticationInfo(Object principal, Object credentials, String realmName) principal: 登陆成功返回给controller登录成功对象 credentials : 该用户在数据库中的密码 realmName: 不需要管理 */ SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(dbUser,dbUser.getPassword(),""); return simpleAuthenticationInfo; } }

对密码加盐加密,编写自定义加盐加密匹配器,增加用户时进行加盐加密,注销用户需销毁session在shiro中的标记。

3.shiro授权

如何实现授权?分为以下两个步骤==

登陆认证成功后,获取用户的权限 (给该用户分配对应的权限)访问资源时候,进行授权校验:用访问资源需要的权限去用户权限列表查找,如果存在,则有权限访问资源。(权限拦截)

shiro提供了四种方式实现权限校验: 1) 硬编码方式(拦截方法)(非Web应用,Web应用)

Subject subject = SecurityUtils.getSubject(); subject.checkPermission("部门管理");

2) 过滤器配置方式(拦截url)(Web应用)

/system/user/list.do = perms["用户管理"]

3) 注解方式(拦截方法)(Web应用)

@RequiresPermissions(“”)

4) shiro提供的标签((拦截页面元素:按钮,表格等))(Web应用)

用户管理 实现自定义realm的doGetAuthorizationInfo()方法,返回用户已经具有的权限。

例:

public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; @Autowired private ModuleService moduleService; //授权方法 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //1. 获取到登陆成功对象 User loginUser = (User) principals.getPrimaryPrincipal(); //2. 查询登陆用户拥有的权限 List moduleList = moduleService.findModuleByUser(loginUser); //3.把权限添加到AuthorizationInfo对象中,这个对象拥有的权限则代表了当前用户拥有权限 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //4. 遍历用户的权限,把权限唯一标识添加到authorizationInfo对象里面 for (Module module : moduleList) { authorizationInfo.addStringPermission(module.getName());//权限标记一般我们都添加 } return authorizationInfo; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3