Apachehiro は Java セキュリティ (権限) フレームワークです。
Shiro は、JavaSE 環境だけでなく JavaEE 環境でも使用できる十分なアプリケーションを簡単に開発できます。 Shiro は、認証、認可、暗号化、セッション管理、Web 統合、キャッシュなど、すべてを行うことができます。
認証: ID 認証、ログイン、ユーザーが対応する権限を持っているかどうかを確認します。 Identity;
Authorization: 認可、つまり権限の検証。認証されたユーザーが特定の権限を持っているかどうかを確認します。つまり、ユーザーが任意の操作を実行できるかどうかを判断します。たとえば、ユーザーが特定のロールを持っているかどうかを確認する、または詳細 ユーザーが特定のリソースに対する特定の権限を持っているかどうかを確認します!
セッション マネージャー: セッション管理、つまりユーザーがログインした後の最初のセッション。終了する前に、そのすべての情報がセッション内にあります。通常の JavaSE 環境であることも、Web 環境であることもできます。
暗号化: パスワード暗号化やプレーン テキスト ストレージではなくデータベースへの保存など、データのセキュリティを保護するための暗号化。Web サポート: Web サポート、 Web 環境に簡単に統合できます。
キャッシュ: たとえば、ユーザーがログインした後、ユーザー情報、ロール、権限を毎回確認する必要がなく、効率が向上します。
同時実行性:Shiro は、マルチスレッド アプリケーションの同時検証をサポートしています。つまり、1 つのスレッドで別のスレッドを開いた場合、権限は自動的に伝達されます。
テスト: テスト サポートを提供します;
実行: 1 人のユーザーがふりをすることを許可します別のユーザー (許可されている場合) でアクセスする;
Remember Me: 私を覚えておいてください、これは非常に一般的な機能です。つまり、一度ログインした後は、次回ログインする必要はありません
Shiro の外側から、つまり、アプリケーションの観点から、Shiro を使用して作業を完了する方法を観察します:
subject: アプリケーション コードが直接対話するオブジェクトは Subject です。これは、Shiro の外部 API のコアが Subject であることを意味し、Subject は現在のユーザーを表します。このユーザーは必ずしも特定の人である必要はありません。現在のユーザーと対話するものはすべて、アプリケーションは、Web クローラー、ロボットなどのサブジェクトです。サブジェクトとのすべての対話は、SecurityManager に委任されます。サブジェクトは、実際にはファサードであり、SecurityManager は実際の実行者です。
SecurityManager: Security Manager、つまり、セキュリティ関連のすべての操作これは、Shiro のコアであり、SpringMVC の
DispatcherServlet
Realm の役割に相当する、Shiro の他のコンポーネントとの対話を担当していることがわかります。 Shiro は Realm からセキュリティ データ (ユーザー、ロール、権限など) を取得します。つまり、SecurityManager はユーザーの ID を確認したいため、ユーザーの ID が正しいかどうかを判断するために、比較のために Realm から対応するユーザーを取得する必要があります。は合法ですが、ユーザーの操作が実行できるかどうかを検証するために、レルムからユーザーに対応するロールと権限を取得する必要もあります。レルムはデータソースとみなすことができます。
セキュリティ マネージャー: SpringMVC の DispatcherServlet に相当; これは、Shiro の中心部で、すべての特定の対話は、すべてのサブジェクトを管理し、認証、認可、セッション、およびキャッシュ管理を担当するセキュリティ マネージャー。
Authorizer: Authorizer、つまり、アクセス コントローラーは、サブジェクトが対応する操作を実行する権限を持っているかどうかを判断するために使用されます。 、ユーザーがアプリケーションでアクセスできる機能を制御します。
Realm: セキュリティ エンティティ データ ソースと見なすことができる 1 つ以上のレルムが存在できます。つまり、DBC を使用して実装できるセキュリティ エンティティを取得するために使用されます。実装等はユーザーが行うため、一般的にアプリケーションでは独自のレルム
SessionManager:セッションのライフサイクルを管理するコンポーネントを実装する必要があり、ShiroはWeb環境だけで利用できるわけではありません
CacheManager: ユーザー、ロール、権限などのキャッシュを管理するキャッシュ コントローラー。これらのデータはめったにアクセスされないため、キャッシュされた後にアクセス パフォーマンスを向上させることができます。
暗号化: 暗号動物学モジュール、Shiro はパスワード暗号化、復号化などのいくつかの一般的な暗号化コンポーネントを改善しました。
<dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.1</version> </dependency> <!-- configure logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.29</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.29</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
5. クイック スタート ケースのリソースの下にある log4j.properties をコピーします
6. hiro.ini ファイルをコピーします
7. Quickstart.java ファイルをコピーします
8. Quickstart.java
public class Quickstart { private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class); public static void main(String[] args) { //工厂模式,通过shiro.ini配置文件中的信息,生成一个工厂实例 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //获取当前的用户对象Subject Subject currentUser = SecurityUtils.getSubject(); //通过当前用户拿到session Session session = currentUser.getSession(); session.setAttribute("someKey", "aValue"); String value = (String) session.getAttribute("someKey"); if (value.equals("aValue")) { log.info("Subject=>session[" + value + "]"); } //判断当前的用户是否被认证 if (!currentUser.isAuthenticated()) { //Token :令牌,没有获取,随机 UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); token.setRememberMe(true); //设置记住我 try { currentUser.login(token); //执行了登录操作 } catch (UnknownAccountException uae) { //如果 用户名不存在 log.info("There is no user with username of " + 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 (AuthenticationException ae) { //意外情况 ? 错误 ? } } //打印其标识主体(在这种情况下,为用户名) log.info("User [" + currentUser.getPrincipal() + "] logged in successfully."); //测试角色是否存在 if (currentUser.hasRole("schwartz")) { log.info("May the Schwartz be with you!"); } else { log.info("Hello, mere mortal."); } //粗粒度,极限范围小 //测试类型化的极限(不是实例级别) if (currentUser.isPermitted("lightsaber:wield")) { log.info("You may use a lightsaber ring. Use it wisely."); } else { log.info("Sorry, lightsaber rings are for schwartz masters only."); } //细粒度,极限范围广 //实例级别的权限(非常强大) 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!"); } //注销 currentUser.logout(); //退出 System.exit(0); } }
#2. SpringBoot と Roku 統合パッケージの依存関係をインポートします
<!--SpringBoot 和 Shiro 整合包--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency>
以下は、設定ファイルを記述するための 3 つの主要な要素です
ShiroSecurityManager はすべてのユーザーを管理します->DefaultWebSecurityManagerRealm接続データ
実際の操作でのオブジェクト作成の順序: レルム -> securityManager -> subject
3. AuthorizingRealm
を継承する必要があるカスタム レルムを作成します。//自定义的 UserRealm extends AuthorizingRealm public class UserRealm extends AuthorizingRealm { //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //打印一个提示 System.out.println("执行了授权方法"); return null; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //打印一个提示 System.out.println("执行了认证方法"); return null; } }
4. 新しい A TaroConfig 構成ファイルを作成します
@Configuration public class ShiroConfig { //ShiroFilterFactoryBean:3 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebsecurityManager); return bean; } //DefaultWebSecurityManager:2 @Bean(name="securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); //关闭UserRealm securityManager.setRealm(userRealm); return securityManager; } //创建realm 对象,需要自定义类:1 @Bean(name="userRealm") public UserRealm userRealm(){ return new UserRealm(); } }
5. テストは成功しました。
2. 使用
@Configuration public class ShiroConfig { //ShiroFilterFactoryBean:3 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebsecurityManager); //添加shiro的内置过滤器 /* anon : 无需认证,就可以访问 authc : 必须认证了才能访问 user : 必须拥有 “记住我” 功能才能用 perms : 拥有对某个资源的权限才能访问 role : 拥有某个角色权限才能访问 */ filterMap.put("/user/add","authc"); filterMap.put("/user/update","authc"); //拦截 Map<String,String> filterMap=new LinkedHashMap<>(); filterMap.put("/user/*","authc"); bean.setFilterChainDefinitionMap(filterMap); // //设置登录的请求 // bean.setLoginUrl("/toLogin"); return bean; }
テスト: 追加リンクをクリックすると、追加ページではなくログイン ページにジャンプします。インターセプトは成功しました
2. ユーザー認証
//登录的方法 @RequestMapping("/login") public String login(String username, String password, Model model) { //获取当前用户 Subject subject = SecurityUtils.getSubject(); //封装用户的登录数据,获得令牌 UsernamePasswordToken token = new UsernamePasswordToken(username, password); //登录 及 异常处理 try { //执行用户登录的方法,如果没有异常就说明OK了 subject.login(token); return "index"; } catch (UnknownAccountException e) { //如果用户名不存在 System.out.println("用户名不存在"); model.addAttribute("msg", "用户名错误"); return "login"; } catch (IncorrectCredentialsException ice) { //如果密码错误 System.out.println("密码错误"); model.addAttribute("msg", "密码错误"); return "login"; } } }
2. Test
カスタム UserRealm に AuthenticationInfo メソッドがあることがわかります。最初に実行され、その後、ログイン関連の操作を実行します。
3. UserRealm の doGetAuthenticationInfo メソッドを変更します。
//认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //打印一个提示 System.out.println("执行了认证方法"); // 用户名密码 String name = "root"; String password = "123456"; //通过参数获取登录的控制器中生成的 令牌 UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //用户名认证 if (!token.getUsername().equals(name)){ // return null UnKnownAccountException return null; } //密码认证, Shiro 自己做,为了避免和密码的接触 //最后返回一个 AuthenticationInfo 接口的实现类,这里选择 SimpleAuthenticationInfo // 三个参数:获取当前用户的认证 ; 密码 ; 认证名 return new SimpleAuthenticationInfo("", password, ""); } }
4. テストして、間違ったパスワードを入力します
正しいパスワードを入力して正常にログインしてください
4.Shiro は Mybatis を統合します
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency>
2. 新しいアプリケーションを作成します .yml
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource #Spring Boot 默认是不注入这些属性值的,需要自己绑定 #druid 数据源专有配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入 #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500 mybatis: type-aliases-package: com.huang.pojo mapper-locations: classpath:mybatis/mapper/*.xml
3.application.propertiesで
mybatis.type-aliases-package=com.longdi.pojo mybatis.mapper-locations=classpath:mapper/*.xml
4.依存関係をインポート
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> <scope>provided</scope> </dependency>
5.Write User class
@Data @AllArgsConstructor @NoArgsConstructor public class User { private int id; private String name; private String pwd; private String perms; }
6. UserMapper の書き込み
@Repository @Mapper public interface UserMapper { public User queryUserByName(String name); }
7. UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.longdi.mapper.UserMapper"> <select id="queryUserByName" resultType="User" parameterType="String"> select * from mybatis.user where name=#{name} </select> </mapper>
の書き込み8. サービス層
UserService インターフェイス:
public interface UserService { public User queryUserByName(String name); }
9. インターフェイスの書き込み実装クラス UserServiceImpl
@Service public class UserServiceImpl implements UserService{ @Autowired UserMapper userMapper; @Override public User queryUserByName(String name) { return userMapper.queryUserByName(name); } }
10.ShiroSpringbootApplicationTests
@SpringBootTest class ShiroSpringbootApplicationTests { @Autowired UserServiceImpl userService; @Test void contextLoads() { System.out.println(userService.queryUserByName("longdi")); } }
11.データベースへの接続成功
5.リクエスト認可の実装
2. コントローラー ジャンプ
3. ログイン インターセプト承認、テスト成功
4. 認可 doGetAuthorizationInfo メソッドを作成します
##5. 認可テストのリクエストが成功しました
6.Shiro は Thymeleaf を統合1.依存関係をインポート<!--shiro和thymeleaf整合--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
4. テスト 5. セッション を挿入します。 6. インデックスを変更します。html
以上がJava で Apache Roku セキュリティ フレームワークを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。