Integration and use SpringBoot in Shiro rights management - with a simple project

Description: This paper with a simple project to explain the use of shiro, the end the project will address attached github for download reference.

shiro's Profile

shiro is a lightweight security framework includes user authentication and user authorization

shiro features:

Authentication (authentication): user identification, commonly referred to as user "login"
the Authorization (authorization): access control. For example, if a user has permission to use an operation.
Session Management (session management): user-specific session management, even in a non-EJB or web application.
Cryptography (encryption): While using an encryption algorithm to encrypt the data source, to ensure ease of use.
More than four points, called Shiro framework of the development team of the four cornerstones of application security.

shiro architecture core API:

Subject: User Principal (the operation to the SecurityManager)
the SecurityManager: Security Manager (manage all Subject, SecurityManager is Shiro core architecture, with interior safety components together to form an umbrella.)
Reaml: bridges, Realm of nature is a data connection shiro specific security the DAO, which encapsulates the data source connection details, to obtain the required data related to Shiro. It is to operate the database, query logins, passwords, permissions, etc.

Shiro configuration class:

Create ShiroFilterFactoryBean; (shiro interceptor, which needs to be disposed to intercept the path, which does not need to be blocked)
created DefaultWebSecurityManager; (for setting the realm)
created Reaml (Inherited AuthorizingReaml);

Shiro built-in filter, you can achieve the relevant authority interceptor:

Common filters:
Anno: No authentication (login) can access
authc: must be certified to access the
user: If you are using rememberMe functions can be accessed directly
perms: The resources must be resources can be accessed
role: the resources must be role permissions to access

shiro use:

When using Shiro, we must first determine what our steps:
1. Add Shiro dependencies
2. Realm achieve their class (class by inheritance AuthorizingRealm);
3. Shiro implemented configuration class
4. The front end of the implement login interface and the preparation of the Controller class

The first step: added dependencies in pom.xml

 <!--添加shiro支持-->
   <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
   </dependency>
   <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.0</version>
   </dependency>

Step 2: Create a custom class MyRealm

We need to create a custom class MyRealm inheritance AuthorizingRealm rewrite doGetAuthenticationInfo and doGetAuthorizationInfo method. DoGetAuthenticationInfo which is used to authenticate users, doGetAuthorizationInfo authorized access control for the user's authority to operate, to prove that the user is allowed to do this operation, such as accessing a link, a resource files.

/**
 * 自定义Realm
 *
 */
public class MyRealm extends AuthorizingRealm {
	@Autowired
	private UserService userService;
	@Autowired
	private RoleMenuMapper roleMenuMapper;
	@Autowired
	private MenuMapper menuMapper;
	@Autowired
	private RoleMapper roleMapper;

	/**
	 * 授权--验证url
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//获取当前登录的用户名
		String name = (String) SecurityUtils.getSubject().getPrincipal();
		// 有了用户就可以拿到对应的角色,有角色就可以拿到对应的菜单
		User user = userService.findByName(name);
		// 这个角色对应 的菜单,先用roleId查找角色和菜单的关联表,再用关联表中的menuId查找对应的menu对象,
		// 再.getPermissions找出权限名
		List<RoleMenu> roleMenuList = roleMenuMapper.findByRoleId(user.getRoleId());//查出所有角色关联的菜单
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		for (RoleMenu roleMenu : roleMenuList) {
			info.addStringPermission(menuMapper.findById(roleMenu.getMenuId()).getPermissions());// 添加权限
		}
		// 设置角色
		Set<String> roles = new HashSet<String>();
		roles.add(roleMapper.findById(user.getRoleId()).getName());
		info.setRoles(roles);
		return info;
	}
	/**
	 * 权限认证--登录
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String name = (String) token.getPrincipal();// 拿到的是用户名 就是UsernamePasswordTokenr的第一个参数 name
		User user = userService.findByName(name);// 根据name找到数据库中的user实体
		if (user != null) {// 这里的一步主要是来判断密码是否正确
			/**
			 * 对于传的三个参数
			 * Object principal:可以传username或者user对象都可以
			 * Object credentials:用户密码:注意这里是指从数据库中获取的password
			 * String realmName:即当前realm的名称(个人尝试:随便传个字符串就行,但不能为null,具体不太明白)
			 */
			return new SimpleAuthenticationInfo(user.getName(), user.getPwd(), "MyRealm");
		} else {
			return null;
		}
	}
}

Step 3: Create Shiro configuration class:

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //必须设置设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //设置没有登录时跳转的页面
        //如果不设置默认会自动寻找web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
         /**
         * 登录成功后要跳转的链接
         * 一般shiro验证成功后,我们需要执行一些操作,比如:缓存用户信息到session,返回页面一些信息等操作
         * 所以,不需要shiro来跳转
         */
        //shiroFilterFactoryBean.setSuccessUrl("/index");
       
         /**
         * 添加拦截器:
         * 常用内置过滤器
         *  anon:无需认证(登录)用户可以直接访问(就相当于游客)
         *  authc:必须要认证才能访问
         *  user:使用了remenberMe的功能的用户可以直接无需登录访问(相当于记住登录状态)
         *  perms:必须获取资源权限才能访问
         *  role:必须获取角色授权才能访问
         *  logout:用户登出,这里不用设置控制器,退出后直接跳转到/
         */
        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        //配置不会被拦截的链接 顺序判断 anon:所有的url都可以匿名访问
        filterMap.put("/static/**","anon");
        filterMap.put("/user/login","anon");
        //配置退出过滤器,其中具体的实现shiro已经替我们实现了
        filterMap.put("/logout", "logout");
        //authc:所有url需要认证才能访问
        filterMap.put("/admin/**", "authc");
        filterMap.put("/houtai/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 创建 安全管理器 SecurityManager
     * @return
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm
        securityManager.setRealm(myRealm());
       return securityManager;
   }
    /**
     * 身份认证realm;(这个需要自己写,账号密码校验,权限等)
     * @return
     */

    @Bean
    public MyRealm myRealm(){
        return new MyRealm();
    }
    
    /**
     * shiro生命周期处理器
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    	return new LifecycleBeanPostProcessor();
    }
    
    /**
     * 开启shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助springAOP扫描使用
     * shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean即可实现此功能
     * @return
     */
    
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
    	DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    	advisorAutoProxyCreator.setProxyTargetClass(true);
    	return advisorAutoProxyCreator;
    }
    
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
    	AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    	authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
    	return authorizationAttributeSourceAdvisor;
    }
    /**
     * 配置 ShiroDialect 用于thymeleaf 和shiro标签配合使用
     * @return
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}

Step Four: Implement front-end login screen and write the Controller class:

Because the interface, like what was the project has, annotation is also more comprehensive, not here at the show.

project address:https://github.com/isczy/BookSystem.git

Here Insert Picture Description

shiro implementation process

1. Start the project, it will load the configuration class ShiroConfig

2. Enter your user name and password, click login have subject.login(token);an operation, it will automatically entrusted to the Security Manager, before calling must SecurityUtils.setSecurityManager () Set

3.SecurityManager responsible for real authentication logic; it will be commissioned to authenticate Authenticator

4.Authenticator put the appropriate token incoming Realm, the Realm obtain identity verification information, if there is no return / exception is thrown by an authentication failed. Here you can configure multiple Realm, will be accessed in the corresponding order and strategy.

5. The method of performing doGetAuthenticationInfo Realm rewrite the custom, user name and password for authentication. Return to normal execution finished, it shows the validation is successful. Otherwise Throws: UnknownAccountException: Password Error: username not / IncorrectCredentialsException exist

When the address 4. Access project, will execute doGetAuthorizationInfo method in a custom Realm rewritten, be authorized to verify url to see whether the user has the authority

shiro certification process map

Here Insert Picture Description

shiro authorization process map

Here Insert Picture Description
Finally, attach the end of the article Project Address:

https://github.com/isczy/BookSystem.git
Published 12 original articles · won praise 22 · views 2602

Guess you like

Origin blog.csdn.net/weixin_45240169/article/details/104036314