欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Shiro应用(一)--- 单独使用

程序员文章站 2022-07-12 15:53:19
...

shiro单独使用demo:

需要的依赖:

		<!-- 日志 --> 
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.25</version>
		</dependency>
		<!-- shiro的核心包 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.4.0</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>

shiro-permissions.ini文件(ini相对于properties文件的区别在于ini文件可以分组):

# -----------------------------------------------------------------------------
# 指定用户名以及角色(可选)
# username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
hurricane = 123, admin,handsome

# -----------------------------------------------------------------------------
# 指定角色与权限的对应关系
# roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = user:add,user:delete
handsome = user:update

简单的日志输出配置log4j.properties:

log4j.rootLogger=info, stdout  
   
log4j.appender.stdout=org.apache.log4j.ConsoleAppender   
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n 

log4j.logger.com.hurricane = info

主要测试代码:

package com.hurricane.learn.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

public class App {

	public static void main(String[] args) {
		Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permissions.ini");
		SecurityManager securityManager = factory.getInstance();
		SecurityUtils.setSecurityManager(securityManager);
		
		Subject subject = SecurityUtils.getSubject();
		AuthenticationToken token = new UsernamePasswordToken("hurricane", "123"); 
		try {
			subject.login(token);
		} catch (UnknownAccountException e) {
			System.out.println("用户名不存在");
		} catch (IncorrectCredentialsException e) {
			System.out.println("密码错误");
		} catch (Exception e) {
			System.out.println("未知错误");
		}
		
		System.out.println("用户登录成功:" + subject.isAuthenticated());
		System.out.println("用户拥有admin角色:" + subject.hasRole("admin"));
		System.out.println("用户拥有user:delete权限:" + subject.isPermitted("user:delete"));
		System.out.println("用户拥有user:query权限:" + subject.isPermitted("user:query"));
	}
}

以上即可实现shiro最基本的使用。

除此之外,shiro单独使用通常需要使用自定义的realm进行校验授权,以及对用户密码进行散列编码。

自定义realm:

shiro-permissions.ini中加入:

[main]
customRealm = com.hurricane.learn.shiro.util.CustomRealm
securityManager.realms = $customRealm

CustomRealm的代码为:

package com.hurricane.learn.shiro.util;

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;

public class CustomRealm extends AuthorizingRealm{

	/**
	 * 授权
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		//primaryPrincipal是认证阶段传入的principal
		Object primaryPrincipal = principals.getPrimaryPrincipal();
		//根据primaryPrincipal从数据库中查询对应的角色与权限,并封装进要返回的AuthorizationInfo
		info.addRole("role1");
		info.addStringPermission("user:create");
		return info;
	}

	/**
	 * 认证
	 * 返回null代表用户名不存在
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		if (token.getPrincipal()==null || token.getPrincipal().toString().equals("")) {
			return null;
		}
		//判断用户名是否存在,若不存在,返回null
		// ...
		String dbPassword = "123";
		//将从数据库中获取的密码传入,shiro会进行校验,此处传入的principal应为工程中对用户信息进行封装的类的实例,此处简写为一个用户名的字符串
		AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),dbPassword,"realm1");
		return info;
	}

}

以上就可以使shiro的校验走自定义的realm。

对密码进行加盐与散列:

shiro-permissions.ini中关于自定义域的声明中指定散列的算法与散列的次数:

[main]
credentialsMatcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName = md5
credentialsMatcher.hashIterations = 2

customRealm = com.hurricane.learn.shiro.util.CustomRealm
customRealm.credentialsMatcher = $credentialsMatcher

securityManager.realms = $customRealm

在进行认证的方法中传入盐与加密后的密码(一般为从数据库中读取的结果),如下:

	/**
	 * 认证
	 * 返回null代表用户名不存在
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		if (token.getPrincipal()==null || token.getPrincipal().toString().equals("")) {
			return null;
		}
		//判断用户名是否存在,若不存在,返回null
		// ...
		//755ac1a684638060155ccc37625b954b是123加盐sss并进行2次md5散列后的结果
		String dbPassword = "755ac1a684638060155ccc37625b954b";
		//将从数据库中获取的密码传入,shiro会进行校验,此处传入的principal应为工程中对用户信息进行封装的类的实例,此处简写为一个用户名的字符串
		AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(),dbPassword,ByteSource.Util.bytes("sss"),"realm1");
		return info;
	}

 

参考:

        燕青的****

        http://shiro.apache.org/tutorial.html

相关标签: Shiro