シロ基本使用まとめ
48915 ワード
1.概要
認証、認可:
認証は簡単に言えば、ログイン時にユーザー名とパスワードが完全に一致しているかどうかを判断することであり、あなたがあなたであることを証明することです.
権限は、認証に基づいて、ロールと権限の付与を行います.権限は、ユーザーがどのような操作を行うことができるかを決定します.
ロール、権限:
パーミッションは、ユーザーが操作を実行できるかどうかを定義します.
ロールは、権限のセットです.
通常、権限のセットを1つのロールにバインドし、1つ以上のロールを1つのユーザーに割り当てることで、権限の制御を実現します.すなわち、権限はロールによってユーザーに定義されます.ロールは権限の集合として、権限の管理を容易にします.
2.簡単なログイン機能を実現shiro依存の追加 プロファイルshiro.ini
3.テストコードの作成Subjectは私たちが登録した主体で、ここは橋に相当して、私たちのすべての操作は実際にSubjectを通じて私たちを助けなければなりません. SecurityManagerはspring MVCのDispatcherServeretに類似しており、フロントエンドコントローラに類似した役割を果たす Realmはセキュリティ・データ・ソースです.ユーザー名やパスワードのような情報をRealmに保存すると、Shiroは認証や認可などの一連の操作を完了するのに役立ちます.この例のRealmはIniRealm と呼ばれています.
3.JDBCRealmを使用
前の例のデータが書かれているプロファイルでは、データベースからデータを読み取ることもできます.依存の追加 プロファイルjdbcRealmを作成する.ini データベース構築
注意:ここで作成したテーブルのテーブル名はusersです.JdbcRealmはデフォルトでusersテーブルのデータを検索します.
JdbcRealmソース
4.試験方法の作成
4.カスタムRealm
方式一:implements Realm
このようにして実現されるRealmは、認証操作のみを実現することができ、認証操作を実現することはできない.
プロファイルを作成するmapRealm.ini
テスト
方式2:extends AuthorizingRealm(認証操作もライセンス操作も実現できるため、比較的一般的な方法)
プロファイルを作成するini
テスト
ナレッジポイントナレッジポイント:資格認定ポリシーの構成
このとき、securityManagerのプロパティがrealmsである以上、いくつかのRealmを設定できることを説明しますが、認証の順序はどうなっていますか.
では、いくつかのRealmについて、Shiroは、複数のReamlが同時に宣言された場合に、どのRealmが返す認証情報を採用するかを決定する構成を提供しています.これが私たちの認証ポリシーです.
認証ポリシーには、主に次の3つがあります.
1、FirstSuccessfulStrategy:Realm認証が成功すれば、最初のRealm認証が成功した認証情報だけを返し、その他は無視する.
2、AtLeastOneSuccessfulStrategy:(これはデフォルトで使用される認証ポリシー、すなわち、構成されていない場合にShiroが採用する認証ポリシー)Realm認証が1つ成功すればよく、FirstSuccessfulStrategyとは異なり、すべてのRealm認証に成功した認証情報を返す.
3、AllSuccessfulStrategy:すべてのRealm検証が成功してこそ成功し、すべてのRealm認証が成功した認証情報を返し、1つの失敗があれば失敗します.
構成例
5.文字列ベースの役割と権限
プロファイルの作成
ロールと権限のテスト
6.カスタム権限解析器とロール解析器
権限解決規則をカスタマイズするには
手順1:Permissionインタフェースの実装
手順2:PermissionResolverインタフェースの実装
PermissionResolverインタフェースを実装する意味は,Shiroが文字列の表現形式(表現特徴)に基づいて,どのようなPermissionを用いてマッチングするかを教えることである.
説明:このコードは、権限文字列が「+」で始まる場合は、カスタムMyPermissionを使用します.そうしないと、デフォルトのWildcardPermissionを使用してこの文字列を解析します.
ステップ3:認証ロジックの実装
プロファイルの作成
カスタムキャラクタマッチング
手順1:RolePermissionResolverインタフェースの実装
手順2:shiro.Iniで我々のRolePermissionResolverを構成する
手順3:カスタムRealmのライセンスメソッドにロールを追加する
ステップ4:認証メソッドで指定したロールに対する権限がユーザーにあるかどうかを判断する
7.暗号化
カスタムRealmの認証実装セクション:
プロファイル
えんを加える
プロファイル
参考記事
http://blog.csdn.net/lw_power?viewmode=contents
Apache Shiro Java , 、 、 。
認証、認可:
認証は簡単に言えば、ログイン時にユーザー名とパスワードが完全に一致しているかどうかを判断することであり、あなたがあなたであることを証明することです.
権限は、認証に基づいて、ロールと権限の付与を行います.権限は、ユーザーがどのような操作を行うことができるかを決定します.
ロール、権限:
パーミッションは、ユーザーが操作を実行できるかどうかを定義します.
ロールは、権限のセットです.
通常、権限のセットを1つのロールにバインドし、1つ以上のロールを1つのユーザーに割り当てることで、権限の制御を実現します.すなわち、権限はロールによってユーザーに定義されます.ロールは権限の集合として、権限の管理を容易にします.
2.簡単なログイン機能を実現
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
[users]
heqianqian = 12345666
3.テストコードの作成
public class SimpleLoginTest {
@Test
public void test() throws Exception {
ShiroUtils.login("classpath:shiro/shiro.ini", "heqianqian", "12345666");
}
}
public class ShiroUtils {
public static Subject getSubject(String path) {
IniSecurityManagerFactory factory = new IniSecurityManagerFactory(path);
SecurityManager manager = factory.getInstance();
SecurityUtils.setSecurityManager(manager);
return SecurityUtils.getSubject();
}
public static Subject login(String path, String userName, String passWord) {
Subject subject = getSubject(path);
UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord);
try {
subject.login(token);
System.out.println(" ");
} catch (UnknownAccountException e) {
System.out.println(" ");
e.printStackTrace();
} catch (IncorrectCredentialsException e) {
System.out.println(" ");
e.printStackTrace();
} catch (AuthenticationException e) {
e.printStackTrace();
}
//subject.logout();
//System.out.println(" ");
return subject;
}
}
3.JDBCRealmを使用
前の例のデータが書かれているプロファイルでは、データベースからデータを読み取ることもできます.
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-coreartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>c3p0groupId>
<artifactId>c3p0artifactId>
<version>0.9.1.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.39version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
[main]
# , 。
##JdbcRealm users
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
dataSource = com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass = com.mysql.jdbc.Driver
dataSource.user = root
dataSource.password = ****
# dataSource jdbcUrl , 。
dataSource.jdbcUrl = jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8
# jdbcRealm dataSource , dataSource , `$`。
jdbcRealm.dataSource = $dataSource
securityManager.realms = $jdbcRealm
DROP DATABASE db_shiro;
# db_shiro
CREATE DATABASE db_shiro DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# db_shiro
USE db_shiro;
drop table if exists users;
create table users(
id int(11) not null auto_increment comment ' ',
username varchar(20) default null comment ' ',
password varchar(20) default null comment ' ',
PRIMARY KEY (id)
)engine=innodb auto_increment=1 default charset=utf8 comment ' ';
insert into users(username,password) values('hqq','123456');
注意:ここで作成したテーブルのテーブル名はusersです.JdbcRealmはデフォルトでusersテーブルのデータを検索します.
JdbcRealmソース
public class JdbcRealm extends AuthorizingRealm {
protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";
protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";
protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";
protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";
...
}
4.試験方法の作成
public class JdbcRealmTest {
private String userName = "heqianqian";
private String passWord = "123";
private Logger logger = Logger.getLogger(JdbcRealmTest.class);
@Test
public void test() throws Exception {
ShiroUtils.login("classpath:shiro/jdbcRealm.ini", userName, passWord);
}
}
4.カスタムRealm
方式一:implements Realm
このようにして実現されるRealmは、認証操作のみを実現することができ、認証操作を実現することはできない.
public class MapRealm implements Realm {
private static Map users = new HashMap<>();
static {
users.put("heqianqian", "123");
users.put("lucy", "456");
}
/**
* Realm
*/
@Override
public String getName() {
System.out.println(" Realm ");
return "My MapRealm";
}
/**
* Token
*/
@Override
public boolean supports(AuthenticationToken authenticationToken) {
System.out.println("Map Realm Token ");
// UsernamePasswordToken Token
return authenticationToken instanceof UsernamePasswordToken;
}
/**
*
*/
@Override
public AuthenticationInfo getAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("Map Realm ");
String userName = (String) authenticationToken.getPrincipal();
String passWord = new String((char[])authenticationToken.getCredentials());
if (!users.containsKey(userName)) {
System.out.println(" !");
} else if (!users.get(userName).equals(passWord)) {
System.out.println(" !");
}
return new SimpleAuthenticationInfo(userName, passWord, getName());
}
}
プロファイルを作成するmapRealm.ini
[main]
# Realm
myMapRealm = heqianqian.shiro.realm.MapRealm
# Realm securityManager realms
securityManager.realms = $myMapRealm
テスト
public class MapRealmTest {
@Test
public void test() throws Exception {
ShiroUtils.login("classpath:shiro/mapRealm.ini","heqianqian","123");
}
}
方式2:extends AuthorizingRealm(認証操作もライセンス操作も実現できるため、比較的一般的な方法)
public class MyStaticRealm extends AuthorizingRealm {
/**
*
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// ,
return null;
}
/**
*
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("Static Realm ");
String userName = authenticationToken.getPrincipal().toString();
String password = new String((char[]) authenticationToken.getCredentials());
if (!"heqianqian".equals(userName)) {
throw new UnknownAccountException(" ");
} else if (!"123".equals(password)) {
throw new IncorrectCredentialsException(" ");
}
return new SimpleAuthenticationInfo("heqianqian", "123", getName());
}
}
プロファイルを作成するini
[main]
myStaticRealm = heqianqian.shiro.realm.MyStaticRealm
securityManager.realms = $myStaticRealm
テスト
@Test
public void testPermission() throws Exception {
Subject subject = ShiroUtils.login("classpath:shiro/mystaticRealm.ini", "heqianqian", "123");
}
ナレッジポイントナレッジポイント:資格認定ポリシーの構成
このとき、securityManagerのプロパティがrealmsである以上、いくつかのRealmを設定できることを説明しますが、認証の順序はどうなっていますか.
では、いくつかのRealmについて、Shiroは、複数のReamlが同時に宣言された場合に、どのRealmが返す認証情報を採用するかを決定する構成を提供しています.これが私たちの認証ポリシーです.
認証ポリシーには、主に次の3つがあります.
1、FirstSuccessfulStrategy:Realm認証が成功すれば、最初のRealm認証が成功した認証情報だけを返し、その他は無視する.
2、AtLeastOneSuccessfulStrategy:(これはデフォルトで使用される認証ポリシー、すなわち、構成されていない場合にShiroが採用する認証ポリシー)Realm認証が1つ成功すればよく、FirstSuccessfulStrategyとは異なり、すべてのRealm認証に成功した認証情報を返す.
3、AllSuccessfulStrategy:すべてのRealm検証が成功してこそ成功し、すべてのRealm認証が成功した認証情報を返し、1つの失敗があれば失敗します.
構成例
#
allSuccessfulStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $allSuccessfulStrategy
5.文字列ベースの役割と権限
プロファイルの作成
[users]
hqq = 123,role1,role2
lucy = 111,role1
[roles]
role1 = user:select
role2 = user:add,user:update,user:delete
ロールと権限のテスト
public class RoleTest {
@Test
public void testHasRole() throws Exception {
Subject subject = ShiroUtils.login("classpath:shiro/shiro-role.ini", "hqq", "123");
assertEquals(true, subject.hasRole("role1"));
assertEquals(true, subject.hasRole("role2"));
assertEquals(true, subject.hasAllRoles(Arrays.asList("role1", "role2")));
subject.logout();
}
@Test
public void testCheckRole() throws Exception {
Subject subject = ShiroUtils.login("classpath:shiro/shiro-role.ini", "hqq", "123");
subject.checkRole("role1");
subject.checkRole("role2");
subject.checkRoles(Arrays.asList("role1", "role2"));
assertEquals(true, subject.hasRole("role2"));
}
}
public class PermissionTest {
@Test
public void testHasPermission() throws Exception {
Subject subject = ShiroUtils.login("classpath:shiro/shiro-permission.ini", "hqq", "123");
assertEquals(true, subject.isPermitted("user:select"));
subject.isPermitted("user:select", "user:add", "user:delete", "user:update");
assertEquals(true, subject.isPermittedAll("user:select", "user:select", "user:add", "user:delete", "user:update"));
subject.logout();
}
@Test
public void testCheckPermission() throws Exception {
Subject subject = ShiroUtils.login("classpath:shiro/shiro-permission.ini", "hqq", "123");
subject.checkPermission("user:select");
subject.checkPermissions("user:select", "user:add", "user:delete", "user:update");
subject.logout();
}
}
6.カスタム権限解析器とロール解析器
権限解決規則をカスタマイズするには
手順1:Permissionインタフェースの実装
public class MyPermission implements Permission {
private String resourceId;
private String operator;
private String instanceId;
public MyPermission() {
}
public MyPermission(String permissionStr) {
String[] strs = permissionStr.split("\\+");
if (strs.length > 1) {
this.resourceId = strs[1];
}
if (this.resourceId == null || "".equals(this.resourceId)) {
this.resourceId = "*";
}
if (strs.length > 2) {
this.operator = strs[2];
}
if (strs.length > 3) {
this.instanceId = strs[3];
}
if (this.instanceId == null || "".equals(this.instanceId)) {
this.instanceId = "*";
}
System.out.println(" MyPermission => " + this.toString());
}
/**
* 【 】
* ,
* , Realm Permission ini PermissionResoler Permission
*
*/
@Override
public boolean implies(Permission permission) {
if (!(permission instanceof MyPermission)) {
return false;
}
MyPermission mp = (MyPermission) permission;
if (!"*".equals(mp.resourceId) && !this.resourceId.equals(mp.resourceId)) {
return false;
}
if (!"*".equals(mp.operator) && !this.operator.equals(mp.operator)) {
return false;
}
if (!"*".equals(mp.instanceId) && !this.instanceId.equals(mp.instanceId)) {
return false;
}
return true;
}
@Override
public String toString() {
return "MyPermission{" +
"resourceId='" + resourceId + '\'' +
", operator='" + operator + '\'' +
", instanceId='" + instanceId + '\'' +
'}';
}
}
手順2:PermissionResolverインタフェースの実装
PermissionResolverインタフェースを実装する意味は,Shiroが文字列の表現形式(表現特徴)に基づいて,どのようなPermissionを用いてマッチングするかを教えることである.
public class MyPermissionResolver implements PermissionResolver {
@Override
public Permission resolvePermission(String s) {
/* “+” , MyPermission , WildcardPermission 。*/
if (s.startsWith("+")) {
return new MyPermission(s);
}
return new WildcardPermission(s);
}
}
説明:このコードは、権限文字列が「+」で始まる場合は、カスタムMyPermissionを使用します.そうしないと、デフォルトのWildcardPermissionを使用してこの文字列を解析します.
ステップ3:認証ロジックの実装
public class MyStaticRealm extends AuthorizingRealm {
/**
*
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("Static Realm ");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole("r1");
info.addRole("r2");
info.addRole("role1");
info.addStringPermission("+user+");
info.addObjectPermission(new MyPermission("+user+add+1"));
return info;
}
/**
*
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("Static Realm ");
String userName = authenticationToken.getPrincipal().toString();
String password = new String((char[]) authenticationToken.getCredentials());
if (!"heqianqian".equals(userName)) {
throw new UnknownAccountException(" ");
} else if (!"123".equals(password)) {
throw new IncorrectCredentialsException(" ");
}
return new SimpleAuthenticationInfo("heqianqian", "123", getName());
}
}
プロファイルの作成
#
permissionResolver = heqianqian.shiro.permission.MyPermissionResolver
authorizer.permissionResolver = permissionResolver
securityManager.authorizer = $authorizer
カスタムキャラクタマッチング
手順1:RolePermissionResolverインタフェースの実装
public class MyRolePermissionResolver implements RolePermissionResolver {
@Override
public Collection resolvePermissionsInRole(String s) {
System.out.println("MyRolePermissionResolver");
if (s.contains("role1")) {
return Arrays.asList((Permission) new MyPermission("+user+add+2"));
}
return null;
}
}
手順2:shiro.Iniで我々のRolePermissionResolverを構成する
authorizer = org.apache.shiro.authz.ModularRealmAuthorizer
## RolePermissionResolver
rolePermissionResolver = heqianqian.shiro.role.MyRolePermissionResolver
authorizer.rolePermissionResolver = rolePermissionResolver
#
permissionResolver = heqianqian.shiro.permission.MyPermissionResolver
authorizer.permissionResolver = permissionResolver
securityManager.authorizer = $authorizer
手順3:カスタムRealmのライセンスメソッドにロールを追加する
public class MyStaticRealm extends AuthorizingRealm {
/**
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("static Realm ");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole("role1");
return info;
}
/**
*
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//
}
}
ステップ4:認証メソッドで指定したロールに対する権限がユーザーにあるかどうかを判断する
currentSubject.checkPermission("+user+add+1");
7.暗号化
PasswordService service = new DefaultPasswordService();
String str1 = service.encryptPassword("123456");
String str2 = service.encryptPassword("123456");
System.out.println(str1);
System.out.println(str2);
//
boolean boolean1 = service.passwordsMatch("123456",str1);
System.out.println(boolean1);
boolean boolean2 = service.passwordsMatch("123456",str2);
System.out.println(boolean2)
カスタムRealmの認証実装セクション:
public class MyPasswordRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
*
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// default
String userName = (String) authenticationToken.getPrincipal();
//String passWordFromDB = "$shiro1$SHA-256$500000$onR5YN4/BqH6toWLn9atsg==$g31FX9UERzy36yBlruzIZqGwCLf8V9P5p3hBrZQOAY0=";
//md5+salt
String passWordFromDB = "c39d11270c99cb00a13a6ac1e54effa2";
String salt = "hqq";
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userName, passWordFromDB, getName());
info.setCredentialsSalt(ByteSource.Util.bytes(salt.getBytes()));
return info;
}
}
プロファイル
# Shiro
passwordMatcher=org.apache.shiro.authc.credential.PasswordMatcher
# Realm
;myPasswordRealm= heqianqian.shiro.realm.MyPasswordRealm
# passwordMatcher Realm
myPasswordRealm.credentialsMatcher=$passwordMatcher
# Realm securityManager
securityManager.realms=$myPasswordRealm
えんを加える
String originPassword = "123456";
String salt = "hello";
String md5 = new Md5Hash(originPassword,salt).toString();
System.out.println(md5);
public class MyPasswordRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = authenticationToken.getPrincipal().toString();
// String password = new String((char[]) authenticationToken.getCredentials());
// username
String passwordFromDB = "eeb9bad681184779aa6570e402d6ef6c";
String salt = "hello";
SimpleAuthenticationInfo info= new SimpleAuthenticationInfo(username,passwordFromDB,getName());
// , ByteSource
info.setCredentialsSalt(ByteSource.Util.bytes(salt.getBytes()));
return info;
}
}
プロファイル
# Shiro
hashMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
hashMatcher.hashAlgorithmName=md5
hashMatcher.hashSalted=hello
# Realm
myPasswordRealm=com.liwei.realm.MyPasswordRealm
# passwordMatcher Realm
myPasswordRealm.credentialsMatcher=$hashMatcher
# Realm securityManager
securityManager.realms=$myPasswordRealm
参考記事
http://blog.csdn.net/lw_power?viewmode=contents