1, Authorization
1. Grant roles to users
① Get the account
② Get the granted role through the user account
③ Give these roles to shiro for management
2. Grant permissions to users
① Get the account
② Get the visible granted permissions through the user account
③ Give these permissions to shiro for management
First, in shirousermapper New content in XML
<select id="getRolesByUserId" resultType="java.lang.String" parameterType="java.lang.Integer"> select r.roleid from t_shiro_user u,t_shiro_user_role ur,t_shiro_role r where u.userid = ur.userid and ur.roleid = r.roleid and u.userid = #{userid} </select> <select id="getPersByUserId" resultType="java.lang.String" parameterType="java.lang.Integer"> select p.permission from t_shiro_user u,t_shiro_user_role ur,t_shiro_role_permission rp,t_shiro_permission p where u.userid = ur.userid and ur.roleid = rp.roleid and rp.perid = p.perid and u.userid = #{userid} </select>
mapper file
Set<String> getRolesByUserId(@Param("userid") Integer userid); Set<String> getPersByUserId(@Param("userid") Integer userid);
service layer
Set<String> getRolesByUserId(Integer userid); Set<String> getPersByUserId(Integer userid);
myRealm file
package com.sjy.shiro; import com.sjy.model.ShiroUser; import com.sjy.service.ShiroUserService; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.stereotype.Service; import java.util.Set; public class MyRealm extends AuthorizingRealm { private ShiroUserService shiroUserService; public ShiroUserService getShiroUserService() { return shiroUserService; } public void setShiroUserService(ShiroUserService shiroUserService) { this.shiroUserService = shiroUserService; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("User authorization..."); String username = principals.getPrimaryPrincipal().toString(); ShiroUser user = shiroUserService.queryByName(username); Set<String> roles = shiroUserService.getRolesByUserId(user.getUserid()); Set<String> pers = shiroUserService.getPersByUserId(user.getUserid()); // SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // info.addRoles(roles); // info.addStringPermissions(pers); SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); info.setRoles(roles); info.setStringPermissions(pers); return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("identity authentication ..."); String username = token.getPrincipal().toString(); String password = token.getCredentials().toString(); ShiroUser user = shiroUserService.queryByName(username); // Get the user information in the database and put it into the token voucher for comparison with the controller AuthenticationInfo info = new SimpleAuthenticationInfo( user.getUsername(), user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName() ); return info; } }
Implementation class
@Override public Set<String> getRolesByUserId(Integer userId) { return shiroUserMapper.getRolesByUserId(userId); } @Override public Set<String> getPersByUserId(Integer userId) { return shiroUserMapper.getPersByUserId(userId); }
When debug runs, you enter the breakpoint, and you can see that the roles are 1 (ordinary users)
After successful login, enter the page
Click Add to enter the breakpoint
Then the following interface appears
When you click add again, you will enter the breakpoint again. It means that shiro will enter the database every time to check whether you have permission. It means that shiro has high security. However, due to the need to access the database every request, the performance is poor. redis cache can be used here
The reason for not having permission is that the permission configured in the ApplicationContext Shiro file is like this
The id of ordinary users in the database is 1, so you should change admin to 1
You will have the right to access it again
2, Annotated development
Introduction to common notes
@Requiresauthentication: indicates that the current subject has passed login authentication; Subject Isauthenticated() returns true
@RequiresUser: indicates that the current Subject has been authenticated or has passed the process of remembering my login
@RequiresGuest: indicates that the current Subject is not authenticated or has logged in by remembering that I am a tourist
@RequiresRoles(value = {"admin","user"},logical = Logical.AND): indicates that the current Subject requires the roles admin and user
@RequiresPermissions(value = {"user:delete","user:b"},logical = Logical.OR): indicates that the current Subject requires permission user:delete or user:b
Create AnnotationController class
package com.sjy.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.authz.annotation.RequiresUser; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class AnnotationController { //Only login can access @RequiresUser @RequestMapping("/passUser") public String passUser(HttpServletRequest request){ return "admin/addUser"; } //Only roles with roleid 1 and 4 can be accessed @RequiresRoles(value = {"1","4"},logical = Logical.AND) @RequestMapping("/passRole") public String passRole(HttpServletRequest request){ return "admin/listUser"; } //Access is only possible with modify and view permissions @RequiresPermissions(value = {"user:update","user:view"},logical = Logical.OR) @RequestMapping("/passPer") public String passPer(HttpServletRequest request){ return "admin/resetPwd"; } @RequestMapping("/unauthorized") public String unauthorized(){ return "unauthorized"; } }
@The Controller annotation is for spring to handle
Annotation controller handles browser requests directly, which means shiro should be used with spring MVC
This means that it should be configured in spring MVC
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true"></property> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException"> unauthorized </prop> </props> </property> <property name="defaultErrorView" value="unauthorized"/> </bean>
Test code
<%-- Created by IntelliJ IDEA. User: Xiaobao's Treasure Date: 2021/12/17 Time: 20:50 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> hello springMVC <ul> shiro annotation <li> <a href="${pageContext.request.contextPath}/passUser">User authentication</a> </li> <li> <a href="${pageContext.request.contextPath}/passRole">role</a> </li> <li> <a href="${pageContext.request.contextPath}/passPer">Authority authentication</a> </li> </ul> </body> </html>
Run code
After logging in, the user authentication can click to jump to
But the role is not authorized. After clicking
Because the path is configured in the configuration file
To access successfully, you must modify the authorization
Change the original and to or, and ordinary users can access it