共通のセキュリティフレームワーク
- apache shhiro
は、あらゆるアプリケーションシステムに適用でき、SpringFrameworkに依存しません。
シンプルで簡単に始められます。
通常、従来のSSMアプリケーションで使用されます。 - Springsecurity
はSpringフレームワークのモジュールの1つであり、Springシステムに依存する必要があります。
より強力で複雑で、
一般的にspringboot + springcloudマイクロサービスの分散開発に使用されます
セキュリティフレームワークの目標
- ユーザー認証ユーザーログイン
- リソース権限管理権限(役割)の制御
shiroフレームワークのアーキテクチャ
説明:
- セキュリティマネージャーセキュリティマネージャー
- オーセンティケーターオーセンティケーターユーザー検証(ログイン)
- 承認者権限管理(制御)
- セッションマネージャーセッションマネージャーはセッションを管理し、さらにセッションを管理します
- セッションDAOはセッションデータを維持します
- キャッシュマネージャーは、メニューデータのキャッシュ管理に使用されます
- 暗号化は、MD5などのパスワードの暗号化アルゴリズムを提供します
- レルムは「レルム」を意味します。主に、認証と承認のビジネスロジックのコンポーネントをカプセル化します。(システムレルムまたはカスタムレルム)
- サブジェクト検証サブジェクト、個人、アプリケーション、アプリ
shiroフレームワークの認証プロセス
Shiroユーザー認証
エントリープログラムの実施手順
- shiroのjarライブラリをインポートする
- shiro構成ファイルの追加* .ini
構文:
– [users]はユーザーリストを定義します
– [main] ini構成ファイルに対応するコンテナーの「ルート」。これはapplicationContext.xmlと同等です。 - テストコード
@Test //入门认证: 使用默认的realm
public void testLoginAndLogout() {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");
SecurityManager securityManger = factory.getInstance();
//构建securityManger环境
SecurityUtils.setSecurityManager(securityManger);
//获取认证的主体
Subject subject = SecurityUtils.getSubject();
//封装认证的令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "111111");
try {
subject.login(token); // 使用默认的系统的realm做用户认证。
} catch (AuthenticationException e) {
e.printStackTrace();
}
System.out.println("是否认证成功:" + subject.isAuthenticated());
subject.logout();
System.out.println("是否认证成功:" + subject.isAuthenticated());
}
結果:
アカウントエラー:org.apache.shiro.authc.UnknownAccountException
パスワードエラー:org.apache.shiro.authc.IncorrectCredentialsException
- カスタムレルム
package com.gec.shiro.realm;
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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
//需继承AuthorizingRealm
public class CustomRealm extends AuthorizingRealm {
//执行认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//先获取用户的帐号
String username = (String) token.getPrincipal();
//伪代码
// User loginUser = userService.findUserByusername(username);
// if(loginUser == null) {
// return null; //报异常:UnknownAccountException
// }
// String password_db = loginUser.getPassword();
String username_db = "zhangsan";
if(!username.equals(username_db)){
return null;
}
String password_db = "111111";
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password_db, "CustomRealm");
return info;
}
//执行授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
}
シロの許可管理
1.リクエストURIに必要な認証IDを設定ファイルで指定する必要があります
<property name="filterChainDefinitions">
<value>
<!-- 所有的静态资源要匿名访问 -->
/bootstrap/**=anon
/css/**=anon
/js/**=anon
/static/**=anon
/images/**=anon
/styles/**=anon
<!-- 授权过滤器 , 建议使用注解授权或在jsp页面使用标签-->
/apply_baoxiao.jsp=perms[baoxiao:apply]
/myBaoxiaoBill=perms[baoxiao:billquery]
/myTaskList=perms[baoxiao:tasklist]
/add_process.jsp=perms[baoxiao:publish]
/processDefinitionList=perms[baoxiao:processlist]
/findUserList=perms[user:query]
/toAddRole=perms[user:create]
/findRoles=perms[baoxiao:rolelist]
/first=user
<!-- 退出系统 -->
/logout=logout
/**=authc
</value>
</property>
2.カスタムレルムでユーザーを承認します
//权限授予
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
//从主体中获取用户信息
ActiveUser activeUser = (ActiveUser) principal.getPrimaryPrincipal();
List<SysPermission> permissions = null;
try {
//从数据库中查找用户的权限信息
permissions = sysService.findPermissionListByUserId(activeUser.getUsercode());
} catch (Exception e) {
e.printStackTrace();
}
List<String> percodes = new ArrayList<>();
for (SysPermission sysPermission : permissions) {
//获取权限信息里的权限标识并加入列表
percodes.add(sysPermission.getPercode());
}
//把权限列表授权给用户
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(percodes);
return info;
}
shiroとssmの統合アプリケーション
基本的な構成は次のとおりです。
- web.xml
<!-- shiro的filter -->
<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置true由servlet容器控制filter的生命周期 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- applicationContext.xmlSpringファイルの構成
<!-- 开启aop,对类代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 开启shiro注解支持 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- web.xml中shiro的filter对应的bean -->
<!-- Shiro 的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<property name="loginUrl" value="/login.action" />
<!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 -->
<property name="successUrl" value="/first.action" />
<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- 自定义filter配置 -->
<property name="filters">
<map>
<!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中-->
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
<!-- 所有的静态资源要匿名访问 -->
/js/**=anon
/images/**=anon
/styles/**=anon
/validatecode.jsp=anon
/items/queryItem.action=perms[item:query]
/items/editItems.action=perms[item:update]
<!-- 退出系统 -->
/logout.action=logout
/**=authc
</value>
</property>
</bean>
<!-- securityManager安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm" />
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- realm -->
<bean id="customRealm" class="cn.items.ssm.shiro.CustomRealm">
<property name="credentialsMatcher" ref="credentialsMatcher" />
</bean>
<!-- 凭证匹配器 -->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="md5" />
<property name="hashIterations" value="2" />
</bean>
<!-- 自定义form认证过虑器 -->
<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
<bean id="formAuthenticationFilter" class="cn.items.ssm.shiro.CustomFormAuthenticationFilter">
<!-- 表单中账号的input名称 -->
<property name="usernameParam" value="username" />
<!-- 表单中密码的input名称 -->
<property name="passwordParam" value="password" />
</bean>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
ユーザー認証プロセスのスケッチ: