您的位置:首页 > 其它

shiro权限认证与授权

2017-03-16 16:49 239 查看

什么是shiro?

Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

为什么要用shiro?

既然可以基于url实现权限的管理,为什么还要用shiro呢??

1.shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。最主要的就是方便了我们的开发。

2.shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。

shiro认证

认证流程:



实例:

1.创建一个Java工程,并加入shiro-core的jar包以及它的依赖包。





2.自定义realm

Shiro有自带的IniRealm,IniRealm从ini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm。

[java] view plain copy







public class CustomRealm extends AuthorizingRealm {

@Override

public String getName() {

return "customRealm";

}

// 用于认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(

AuthenticationToken token) throws AuthenticationException {

// token是用户输入的

// 第一步从token中取出身份信息

String userCode = (String) token.getPrincipal();

// 第二步:根据用户输入的userCode从数据库中查询

// 模拟从数据库查询到密码

String password = "111111";

// 如果查询到返回认证信息AuthenticationInfo

SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(

userCode, password, this.getName());

return simpleAuthenticationInfo;

}

}

3.配置shiro-realm.ini文件



[html] view plain copy







[main]

#自定义realm

customRealm=cn.itcast.shiro.realm.CustomRealm

#将realm设置到securityManager,相当于spring中注入

securityManager.realms=$customRealm

4.创建认证代码

[java] view plain copy







// 用户登录和退出

@Test

public void testCustomRealm() {

// 创建securityManager工厂,通过ini配置文件创建securityManager工厂

Factory<SecurityManager> factory = new IniSecurityManagerFactory(

"classpath:shiro-realm.ini");

// 通过工厂创建SecurityManager

SecurityManager securityManager = factory.getInstance();

// 将securityManager设置到运行环境中

SecurityUtils.setSecurityManager(securityManager);

// 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行

Subject subject = SecurityUtils.getSubject();

// 创建token令牌,记录用户认证的身份和凭证即账号和密码

UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",

"111111");

try {

// 用户登陆

subject.login(token);

} catch (AuthenticationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// 用户认证状态

Boolean isAuthenticated = subject.isAuthenticated();

System.out.println("用户认证状态:" + isAuthenticated);

// 用户退出

subject.logout();

isAuthenticated = subject.isAuthenticated();

System.out.println("用户认证状态:" + isAuthenticated);

}

5.认证流程

(1)创建token令牌,token中有用户提交的认证信息即账号和密码

(2)执行subject.login(token),最终由securityManager通过Authenticator进行认证

(3)Authenticator的实现ModularRealmAuthenticator调用realm从数据库中取用户真实的账号和密码

(4)CustomRealm先根据token中的账号去数据库中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

6.测试



登录时用户认证成功,退出时用户认证失败。

shiro授权

授权流程



授权方式

shiro支持三种方式的授权:

1.编程式

[java] view plain copy







Subject subject = SecurityUtils.getSubject();

if(subject.hasPermission(“admin”)) {

//有权限

} else {

//无权限

}

2.注解式

[java] view plain copy







@RequiresPermissions("admin")

public void hello() {

//有权限

}

3.JSP/GSP标签

[java] view plain copy







<shiro:hasPermission name="admin">

<!— 有权限—>

</shiro:hasRole>

在web系统集成中使用后两种方式,我在这儿举个简单的例子就用第一种方式了。

实例

1.自定义realm

[java] view plain copy







// 用于授权

@Override

protected AuthorizationInfo doGetAuthorizationInfo(

PrincipalCollection principals) {

// 获取身份信息

//将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到Simpl)

String username = (String) principals.getPrimaryPrincipal();

// 根据身份信息从数据库中查询权限数据

// ....这里使用静态数据模拟

List<String> permissions = new ArrayList<String>();

permissions.add("user:create");

permissions.add("user:delete");

// 将权限信息封闭为AuthorizationInfo

SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

for (String permission : permissions) {

simpleAuthorizationInfo.addStringPermission(permission);

}

return simpleAuthorizationInfo;

}

2.配置shiro-realm.ini文件与上面认证配置文件相同

3.创建授权代码

[java] view plain copy







// 自定义realm进行资源授权测试

@Test

public void testAuthorizationCustomRealm() {

// 从ini文件中创建SecurityManager工厂

Factory<SecurityManager> factory = new IniSecurityManagerFactory(

"classpath:shiro-realm.ini");

// 创建SecurityManager

SecurityManager securityManager = factory.getInstance();

// 将securityManager设置到运行环境

SecurityUtils.setSecurityManager(securityManager);

// 创建主体对象

Subject subject = SecurityUtils.getSubject();

// 对主体对象进行认证

// 用户登陆

// 设置用户认证的身份(principals)和凭证(credentials)

UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",

"111111");

try {

subject.login(token);

} catch (AuthenticationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// 用户认证状态

Boolean isAuthenticated = subject.isAuthenticated();

System.out.println("用户认证状态:" + isAuthenticated);

// 授权检测,失败则抛出异常

// subject.checkRole("role22");

// 基于资源授权

System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));

System.out.println("是否拥有多个权限:"

+ subject.isPermittedAll("user:update", "user:delete"));

// 检查权限

subject.checkPermission("user:delete");

}

4.授权流程

(1)执行subject.isPermitted("user:delete")

(2)securityManager通过ModularRealmAuthorizer进行授权

(3)ModularRealmAuthorizer调用realm获取权限信息

(4)ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

5.测试



表明该用户拥有delete权限但是不拥有update权限。

转载:http://blog.csdn.net/u010539352/article/details/51220276
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: