shiro licensing and annotated development

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

 

Keywords: Java Spring Back-end security

Added by Mindwreck on Thu, 23 Dec 2021 14:30:17 +0200