Shiro安全框架

xiaoxiao2021-02-28  127

Shiro安全框架

引言: 当用户在浏览器中直接输入请求实现跳转,这样是不安全的, 当用户登陆系统,看到不应该是整个系统功能,这就需要相应的权限控制, 过程中,需要用到Shiro安全框架。

Shiro安全框架是Apache基金会旗下一款安全框架, 其中包括登陆认证\权限控制\session管理\加密处理 这四大模块

1.Shiro安全框架中的其中四大模块

Authentication 登陆认证

Authorization 权限认证

SessionManagement 安全管理

Cryptography 加密模块

2.Shrio内部流程图 ApplicationCode 应用的代码/线程/机器,这些都会发起请求,进行安全验证。

Subject 是Shiro对外暴露的唯一入口程序 如果用户需要进行验证,则必须经过Subject才能到达Shiro内部进行校验,否则任何认证都不生效。 (相当于进家门的那扇门) 只要当前请求Shiro程序并经过了Subject,那么当前的请求就是一个”user”.

ShiroSecurityManager Shiro安全中心,这是Shiro中最为核心的部分。 如果用户需要进行安全的校验,则Shiro安全中心内部会有自己的校验规则, 这时Shiro自己调用安全规则进行校验,无需程序员干预.

Realm 原材料 当Shiro安全中心需要进行校验时,通过Realm查询用户真实数据,返回给安全中心, 由安全中心内部自己做校验

完整流程的例子: 当用户输入用户名和密码时,首先经过Subject进行提交数据,数据提交到Shiro安全中心后, Shiro安全中心通过调用Realm查询真实的用户信息,将用户信息返回安全中心后, Shiro安全中心内部将2个信息做比较,如果匹配则登陆成功。

3.Shiro安全框架的搭建

1.导入Shiro Jar包

<!-- Apache Shiro 权限架构 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.8.3</version> </dependency>

2.编辑配置文件

1.自定义Realm配置 public class AuthRealm extends AuthorizingRealm{ @Resource private UserService userService; @Override //权限控制 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } @Override //登陆认证模块 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { return null; }

2.定义过滤器

<!--Shiro的过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!--配置安全中心 --> <property name="securityManager" ref="securityManager"></property> <!--指定登陆的地址 当用户没有登陆时,默认跳转该页面--> <property name="loginUrl" value="/index.jsp"></property> <!--过滤器链 --> <property name="filterChainDefinitions"> <value> <!--添加过滤信息 --> </value> </property> </bean>

3.将Shiro过滤器交给web容器管理

<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!--将Shiro过滤器生命周期,交给web容器管理 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter>

4.Shiro的登陆设置

1.必须经过subject

//用户名和密码不为空 //Shiro的的登陆操作 获取用户对象 Subject subject = SecurityUtils.getSubject(); //将用户数据封装为令牌 UsernamePasswordToken token = new UsernamePasswordToken(userName,password); try { //通过用户实现登陆 subject.login(token); //执行到证明用户名密码正确 return "redirect:/home.action" } catch (AuthenticationException e) { e.printStackTrace();//打印异常信息 //证明用户名密码错误 model.addAttribute("errorInfo", "用户名或密码不能为空"); return "/sysadmin/login/login"; } 2.编译自定义的Realm @Override //登陆认证模块 protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { //通过realm 返回给安全中心 真实的用户信息 //获取用户名 UsernamePasswordToken loginToken = (UsernamePasswordToken) token; //获取用户名 String username = loginToken.getUsername(); //表示真实信息 User uer = userService.findUserByUserName(username); /* * 参数介绍 * principal真实的对象 * credentials 表示真实的密码 * realmName 表示当前的realm */ AuthenticationInfo info = new SimpleAuthenticationInfo( user, user.getPassword, this.getName()); return info; 3.Shiro内部加密算法 //Shiro内部加密算法 public class AuthCredential extends SimpleCredentialsMatcher{ @Override public boolean doCredentialsMatch(AuthenticationToken token,AuthenticationInfo info) { UsernamePasswordToken loginToken = (UsernamePasswordToken) token; //将密码进行加密 String username = loginToken.getUsername(); String Password = String.valueOf(loginToken.getPassword();) System.out.println("输出明文:"+password); String md5Password = Md5Password.getMd5HashPassword(Password,username); loginToken.setPassword(md5Password.toCharArray()); ruturn super.doCredentialsMatch(loginToken, info); } 4.将加密器交给Spring管理 <!--自己编辑Realm为安全中心提供信息 --> <bean id="AuthRealm" class="cn.xxxx.xx.shiro.AuthRealm"> <property name="credentialsMatcher" ref="authCreadential"></property> </bean> <!--自定义加密算法 --> <bean id="authCredential" class="cn.xxxx.xx.shiro.AuthCredential"/> 5.获取真实的用户对象那个和sess``` try { //通过用户实现登陆 subject.login(token); //获取真实用户对象 User user = (User)subject.getPrincipal(); //session.setAttribute("sessionUser", user); subject.getSession().setAttribute("sessionUser", user); 执行到证明用户名密码正确 return "redirect:/home.action" } catch (AuthenticationException e) { e.printStackTrace();//打印异常信息 //证明用户名密码错误 model.addAttribute("errorInfo", "用户名或密码不能为空"); return "/sysadmin/login/login"; }
转载请注明原文地址: https://www.6miu.com/read-23169.html

最新回复(0)