APP下载
报价宝  ›  科技  › 

SSM整合Shiro实现认证、加密和授权

报价宝 来源:baojiabao.com 发布时间:2019-11-01 23:59:00 10月25日更新
报价宝综合消息SSM整合Shiro实现认证、加密和授权

学习目标

1、shiro介绍

2、SSM整合Shiro

学习内容

1.shiro介绍

1.1介绍

shiro是一个java的 安全框架,apache的一个开源框架。简单易用。实现的功能:认证、授权、会话管理和密码加密等功能。可以用在java SE环境中,java EE环境中。1.2shrio功能特点:

Authentication:认证

Authorization:授权

Session Management:session会话管理

Cryptography:密码加密

Caching:快取

web Support:web支援

Concurrency:多执行绪、并发

Testing:测试

Run as: 以 某种 身份 执行

Remember Me:记住我

1.3shiro执行原理

可以看到:应用程序码直接互动的物件是Subject,也就是说Shiro的对外API核心就是Subject;其每个API的含义:

Subject:主体,抽象的身份:当前的使用者,网络爬虫、第三方的程式、程序

SecurityManager:安全管理器,管理所有的subjects;委托给SecurityManager进行安全管理。门面模式:Facade;需求----》委托人————分发下去;

Realm:域,资料域。获取数据库中使用者资讯、许可权资讯。

接下来我们来从Shiro内部来看下Shiro的架构,如下图所示:

1.4过滤器

Shiro内建了很多预设的拦截器,比如身份验证、授权等相关的。预设拦截器可以参考org.apache.shiro.web.filter.mgt.DefaultFilter中的列举拦截器:

解释:

/admins/**=anon # 表示该 uri 可以匿名访问/admins/**=auth # 表示该 uri 需要认证才能访问/admins/**=authcBasic # 表示该 uri 需要 httpBasic 认证/admins/*=perms[user:add:] # 表示该 uri 需要认证使用者拥有 user:add:* 许可权才能访问/admins/**=port[8081] # 表示该 uri 需要使用 8081 埠/admins/=rest[user] # 相当于 /admins/=perms[user:method],其中,method 表示 get、post、delete 等/admins/**=roles[admin] # 表示该 uri 需要认证使用者拥有 admin 角色才能访问/admins/**=ssl # 表示该 uri 需要使用 https 协议/admins/**=user # 表示该 uri 需要认证或通过记住我认证才能访问/logout=logout # 表示登出,可以当作固定配置注意:

anon,authcBasic,auchc,user 是认证过滤器。perms,roles,ssl,rest,port 是授权过滤器。

2、shiro的hello world

参考官网的示例

public static void main(String[] args) {

//初始化工厂例项

Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");

//例项化一个安全管理器

SecurityManager securityManager = factory.getInstance();

//设定安全管理器

SecurityUtils.setSecurityManager(securityManager);

//获取Subject:当前使用者

Subject currentUser = SecurityUtils.getSubject();

​

//从session中查询中当前登入的使用者资讯 ,类似于登入时从session中获取登入资讯

Session session = currentUser.getSession();

session.setAttribute("someKey", "aValue");

String value = (String) session.getAttribute("someKey");

if (value.equals("aValue")) {

log.info("Retrieved the correct value! [" + value + "]");

}

// let's login the current user so we can check against roles and permissions:

//如果当前使用者还没有认证

if (!currentUser.isAuthenticated()) {

//身份令牌:使用者名称和密码 ;实际从前台登入页面获取

UsernamePasswordToken token = new UsernamePasswordToken("root", "secret");

//记住我

token.setRememberMe(true);

try {

//模拟登入 :会将身份令牌资讯传给安全管理器,委托给安全管理器进行认证

currentUser.login(token);

} catch (UnknownAccountException uae) { //账号不存在

log.info("没有该账号 " + token.getPrincipal());

} catch (IncorrectCredentialsException ice) { //密码不匹配

log.info("Password for account " + token.getPrincipal() + " was incorrect!");

} catch (LockedAccountException lae) {//账号锁定

log.info("The account for username " + token.getPrincipal() + " is locked. " +

"Please contact your administrator to unlock it.");

}

// ... catch more exceptions here (maybe custom ones specific to your application?

catch (AuthenticationException ae) { //认证异常

//unexpected condition? error?

}

}

//say who they are:

//print their identifying principal (in this case, a username):

log.info("使用者 [" + currentUser.getPrincipal() + "] 登入成功.");

​

//角色判断

//test a role:

if (currentUser.hasRole("schwartz")) {

log.info("May the Schwartz be with you!");

} else {

log.info("Hello, mere mortal.");

}

//许可权判断

//test a typed permission (not instance-level)

if (currentUser.isPermitted("lightsaber:weild")) {

log.info("You may use a lightsaber ring. Use it wisely.");

} else {

log.info("Sorry, lightsaber rings are for schwartz masters only.");

}

​

//a (very powerful) Instance Level permission:

if (currentUser.isPermitted("winnebago:drive:eagle5")) {

log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +

"Here are the keys - have fun!");

} else {

log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");

}

//all done - log out!

//登出

currentUser.logout();

System.exit(0);

}

3、SSM整合+shiro认证

步骤:

1、新增依赖

org.apache.shiro

shiro-core

${shiro.version}

org.apache.shiro

shiro-ehcache

${shiro.version}

org.apache.shiro

shiro-spring

${shiro.version}

org.apache.shiro

shiro-web

${shiro.version}

2、配置web.xml中的shiro的过滤器

shiroFilter

org.springframework.web.filter.DelegatingFilterProxy

targetFilterLifecycle

true

​

shiroFilter

/*

3、配置shiro.xml档案

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

​

​

​

​

​

​

​

​

​

​

​

​

​

​

/index.jsp=anon

/user/login=anon

/user/logout=logout

/static/**=anon

/admin/**= authc

登入认证:

4、设定控制器中的登入方法:

@Controller

@RequestMapping("/user")

public class UserController {

​

@RequestMapping("/login")

public String login(User user){

System.out.println("登入:"+user);

//身份令牌

UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(), user.getPassword());

Subject currentUser=SecurityUtils.getSubject();

​

token.setRememberMe(true);

try {

currentUser.login(token);

} catch (UnknownAccountException e){

throw new UnknownAccountException(e.getMessage());

} catch (IncorrectCredentialsException e){

throw new IncorrectCredentialsException(e.getMessage());

}catch (AuthenticationException e) {

throw new AuthenticationException(e.getMessage());

}

return "admin/index";

}

}

​

5、建立Realm类

public class MyRealm extends AuthenticatingRealm {

// 实现使用者的身份认证

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("开始身份认证:");

//获取使用者名称 :从登入页面传递过来的使用者名称

// authenticationToken.getPrincipal();

UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;

String username=token.getUsername();//获取使用者名称

​

//查询资料是否存在使用者名称

System.out.println("使用者名称:"+username);

// 根据使用者名称:账号;从资料中查询该使用者名称对应的密码

​

String password="abcdef";

​

Object principal=username;

Object credentials=password;

String realmName=getName();

​

//存的从数据库取出来的使用者名称字 和密码

AuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials,realmName);

return info;

}

​

​

}

密码加密

常见的 对称加密 算法主要有 DES、3DES、AES 等,常见的 非对称算法 主要有 RSA、DSA 等,杂凑算法 主要有 SHA-1、MD5 等。

使用杂凑算法:

hashAlgorithmName:加密的算法名称 MD5(不可逆的)

credentials:密码

salt:盐(使用者名称+随机数字)

hashIterations:迭代次数

new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations)

realm中的认证:

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

System.out.println("开始身份认证:");

//获取使用者名称 :从登入页面传递过来的使用者名称

// authenticationToken.getPrincipal();

UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;

String username=token.getUsername();//获取使用者名称

​

//查询资料是否存在使用者名称

System.out.println("使用者名称:"+username);

// 根据使用者名称:账号;从资料中查询该使用者名称对应的密码

​

//模拟从数据库中取出加密后的密码

Object credentials="f7b5cd56c1e2d49e5b69c9dde7679ca4";

if("test".equals(username)){

//123456

credentials="4292bb58be34c59d28a0dcbd11932d49";

} else if("admin".equals(username)){

//abcdef

credentials="f7b5cd56c1e2d49e5b69c9dde7679ca4";

}

​

Object principal=username;

// Object credentials=password;

String realmName=getName();

//盐 :以使用者名称充当盐值

ByteSource credentialsSalt= ByteSource.Util.bytes(username);

//从数据库取出来的 使用者名称字 和 加密后的密码

AuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName);

return info;

}

授权

不同的使用者---》角色----》许可权

资料表:使用者表、角色表、选单表,使用者角色关联表,角色选单关联表;

A角色 A资源(表、实体)) create

update

delete

query

资源:动作

shiro支援3种方式的授权验证:

1、编码

验证角色

//get the current Subject

Subject currentUser = SecurityUtils.getSubject();

​

if (currentUser.hasRole("administrator")) {

//show a special button•

} else {

//don’t show the button?)•

}

验证许可权

Subject currentUser = SecurityUtils.getSubject();

​

Permission printPermission = new PrinterPermission("laserjet3000n","print");

​

If (currentUser.isPermitted(printPermission)) {

//do one thing (show the print button?)•

} else {

//don’t show the button?

}

String perm = "printer:print:laserjet4400n";

​

if(currentUser.isPermitted(perm)){

//show the print button?

} else {

//don’t show the button?

}

2、注解

//Will throw an AuthorizationException if none

//of the caller’s roles imply the Account

//'create' permission

@RequiresPermissions("account:create")•

public void openAccount( Account acct ) {

//create the account

}

//Throws an AuthorizationException if the caller

//doesn’t have the ‘teller’ role:

@RequiresRoles( "teller" )

public void openAccount( Account acct ) {

//do something in here that only a teller

//should do

}

需要开启注解配置:

3、标签

Click here to manage users

No user management for you!

修改MyRealm类:

//实现授权

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

Object username= principals.getPrimaryPrincipal();

//根据使用者名称获取对应的角色,模拟从数据库中获取角色列表

Set roles=new HashSet();

roles.add("admin");

roles.add("guest");

roles.add("test");

// 返回的对应的 AuthorizationInfo的实现类的物件

SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();

//系结角色列表

info.setRoles(roles);

// 系结许可权列表

// info.setStringPermissions();

return info;

}

在相应的控制器中增加注解方式的角色或者许可权判断,根据返回的异常进行处理。

文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 报价宝 汽车价格 笔记本价格 笔记本电脑价格 降噪耳机价格