Heim > Java > javaLernprogramm > Hauptteil

So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

WBOY
Freigeben: 2023-04-18 19:40:10
nach vorne
1028 Leute haben es durchsucht

    1. Einführung in Shiro:

    Apache Shiro ist ein Java-Sicherheits-(Berechtigungs-)Framework.
    Shiro macht es sehr einfach, ausreichend gute Anwendungen zu entwickeln, die nicht nur in der JavaSE-Umgebung, sondern auch in der JavaEE-Umgebung verwendet werden können. Shiro kann alles: Authentifizierung, Autorisierung, Verschlüsselung, Sitzungsverwaltung, Webintegration, Caching und mehr.

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    shiro-Funktionen:

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    Authentifizierung: Identitätsauthentifizierung, Anmeldung, Überprüfung, ob der Benutzer über die entsprechende Identität verfügt;
    Autorisierung: Autorisierung, d. h. Berechtigungsüberprüfung, Überprüfung, ob ein authentifizierter Benutzer über bestimmte Berechtigungen verfügt , das heißt, es wird bestimmt, welche Vorgänge ein Benutzer ausführen kann, z. B.: Überprüfen, ob ein Benutzer eine bestimmte Rolle hat, oder differenzierte Überprüfung, ob ein Benutzer eine bestimmte Berechtigung für eine bestimmte Ressource hat
    Sitzungsmanager: Sitzungsverwaltung, das heißt , Benutzer Nach dem Anmelden handelt es sich um die erste Sitzung. Vor dem Abmelden können sich alle Informationen in der Sitzung befinden.
    Kryptografie: Verschlüsselung, Schutz der Datensicherheit Passwortverschlüsselung. Wird in der Datenbank statt im Klartext gespeichert Dies kann die Effizienz verbessern.
    Parallelität: Shiro unterstützt die gleichzeitige Überprüfung von Multithread-Anwendungen. Das heißt, wenn Sie einen anderen Thread in einem Thread starten, können die Berechtigungen automatisch an ihn weitergegeben werden.
    Testen: Testen support;
    Ausführen als: Ermöglicht einem Benutzer, Zugriff als ein anderer Benutzer vorzutäuschen (sofern er dies zulässt);
    An mich erinnern: An mich erinnern, dies ist eine sehr häufige Funktion, das heißt, nach einmaliger Anmeldung ist dies nicht mehr erforderlich Melden Sie sich das nächste Mal an

    Shiro-Architektur (extern)

    Betrachten Sie Shiro von außen, das heißt, beobachten Sie, wie Shiro verwendet wird, um Arbeiten aus der Perspektive der Anwendung abzuschließen:

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    Betreff: Das Objekt, das die Anwendung verwendet Der Code interagiert direkt mit dem Subjekt, was bedeutet, dass der Kern der externen API von Shiro das Subjekt ist und das Subjekt den aktuellen Benutzer darstellt. Dieser Benutzer ist nicht unbedingt eine bestimmte Person. Alles, was mit der aktuellen Anwendung interagiert, ist ein Subjekt, wie zum Beispiel Webcrawler , Roboter usw. Alle Interaktionen mit dem Subjekt werden an den SecurityManager delegiert. Der Subjekt ist tatsächlich eine Fassade, und der SecurityManager ist der eigentliche Ausführende

    SecurityManager: Sicherheitsmanager, das heißt, alle sicherheitsrelevanten Vorgänge interagieren mit SecurityManager. und es verwaltet alle Subjekte. Es ist ersichtlich, dass es der Kern von Shiro ist und für die Interaktion mit anderen Komponenten von Shiro verantwortlich ist. Es entspricht der Rolle von SpringMVCs
    DispatcherServlet
    Realm: Shiro erhält Sicherheitsdaten (z. B Das heißt, wenn SecurityManager die Identität des Benutzers überprüfen möchte, muss er zum Vergleich den entsprechenden Benutzer von Realm abrufen, um festzustellen, ob die Identität des Benutzers zulässig ist Die entsprechende Rolle und die Berechtigungen des Benutzers aus dem Bereich, um zu überprüfen, ob der Vorgang des Benutzers als DataSource ausgeführt werden kann; Anwendung;
    Sicherheitsmanager: Entspricht dem DispatcherServlet in SpringMVC. Alle spezifischen Interaktionen werden durch den Sicherheitsmanager verwaltet. Er ist für die Authentifizierung, Autorisierung und Cache-Verwaltung verantwortlich.

    Authenticator: Verantwortlich für die Betreffauthentifizierung, es ist ein Erweiterungspunkt und kann angepasst werden. Sie können die Authentifizierungsstrategie (AuthenticationStrategy) verwenden, d. h. unter welchen Umständen wird die Benutzerauthentifizierung durchgeführt? Der Controller wird verwendet, um zu bestimmen, ob das Subjekt die Berechtigung hat, entsprechende Vorgänge auszuführen. Das heißt, er steuert, auf welche Funktionen in der Anwendung der Benutzer zugreifen kann.

    Realm: Es kann einen oder mehrere Bereiche geben, die als sichere Entitätsdaten betrachtet werden können Die Quelle, die zum Abrufen von Sicherheitsentitäten verwendet wird, kann mithilfe von DBC oder einer vom Benutzer bereitgestellten Speicherimplementierung usw. implementiert werden. Daher müssen Sie in Anwendungen im Allgemeinen Ihren eigenen Bereich implementieren. SessionManager: eine Komponente, die die Sitzungslebensdauer verwaltet Zyklus, und Shiro kann nicht nur in der Webumgebung verwendet werden, sondern auch in der normalen JavaSE-Umgebung

    CacheManager: Cache-Controller zum Verwalten von Caches wie Benutzern, Rollen, Berechtigungen usw., da auf diese Daten grundsätzlich selten zugegriffen werden kann. Der Zugriff kann verbessert werden, nachdem er in den Cache gestellt wurde. So verwenden Sie das Apache Shiro-Sicherheitsframework in JavaKryptographie: Kryptographiemodul, Shiro verbessert einige gängige Verschlüsselungskomponenten für Passwortverschlüsselung, Entschlüsselung usw.

    2. Schnellstart

    1 Auf der offiziellen Website werden Sie aufgefordert, die GitHub-Adresse für den Schnellstart zu finden: shiro/samples/quickstart/





    2 Erstellen Sie ein neues Maven-Projekt, löschen Sie dessen src-Verzeichnis und verwenden Sie es als übergeordnetes Projekt Neues Maven-Modul im übergeordneten Projekt

    4. Kopieren Sie die Schnellstart-Fallabhängigkeiten in XML-Dateien
    <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>
    Nach dem Login kopieren

    5. Kopieren Sie die log4j.properties unter der Ressource im Schnellstartfall

    6. Kopieren Sie den Quickstart. Java-Datei

    8. Führen Sie Quickstart.java

    2 aus. 3. SpringBoot integriert ShiroSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    1. Schreiben Sie eine Testumgebung

    1. Erstellen Sie gerade ein neues Springboot-Modul im übergeordneten Projekt

    #🎜 🎜 #

    2. Importieren Sie die Abhängigkeiten des SpringBoot- und Shiro-Integrationspakets

    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 &#39;drive&#39; the winnebago with license plate (id) &#39;eagle5&#39;.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren&#39;t allowed to drive the &#39;eagle5&#39; winnebago!");
            }
            //注销
            currentUser.logout();
            //退出
            System.exit(0);
        }
    }
    Nach dem Login kopieren

    Das Folgende sind die drei Hauptelemente zum Schreiben von Konfigurationsdateien

    ShiroSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    # 🎜🎜#Subjektbenutzer-> ShiroFilterFactoryBean

    SecurityManager verwaltet alle Benutzer-> DefaultWebSecurityManager

    Realm-Verbindungsdaten


    Die Reihenfolge der Objekterstellung im tatsächlichen Betrieb: Bereich - > securityManager -> subject

    3. Erstellen Sie eine neue ShiroConfig-Konfigurationsdatei

     <!--SpringBoot 和 Shiro 整合包-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.1</version>
            </dependency>
    Nach dem Login kopieren
    #🎜🎜 #5. Test erfolgreich!

    2. Verwenden Sie

    1. Fügen Sie das erforderliche Abfangen in der getShiroFilterFactoryBean hinzu Methode Anmeldeanforderung

    //自定义的 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;
        }
    }
    Nach dem Login kopieren

    Test: Durch Klicken auf den Link „Hinzufügen“ wird nicht zur Hinzufügen-Seite, sondern zur Anmeldeseite gesprungen, und das Abfangen ist erfolgreich

    # 🎜🎜# So verwenden Sie das Apache Shiro-Sicherheitsframework in Java2. Benutzerauthentifizierung

    1 Schreiben Sie eine Anmeldemethode in der Controller-Ebene

    @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();
        }
    }
    Nach dem Login kopieren
    2. 🎜🎜#

    Es ist ersichtlich, dass zuerst die AuthenticationInfo-Methode im angepassten UserRealm ausgeführt wird und dann die anmeldebezogenen Vorgänge ausgeführt werden

    3 Ändern Sie die doGetAuthenticationInfo-Methode im UserRealm

    @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;
        }
    Nach dem Login kopieren

    4. Geben Sie das falsche Passwort einSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    #🎜 🎜#Geben Sie das richtige Passwort ein. Sie können sich erfolgreich anmelden.

    4. Shiro integriert Mybatis neue application.ymlSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    //登录的方法
        @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";
            }
        }
    }
    Nach dem Login kopieren

    3. In application.properties

    //认证
        @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, "");
        }
    }
    Nach dem Login kopieren

    4.Abhängigkeiten importieren

    <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>
    Nach dem Login kopieren

    5.Write User class

    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
    Nach dem Login kopieren

    6.UserMapper schreiben

    mybatis.type-aliases-package=com.longdi.pojo
    mybatis.mapper-locations=classpath:mapper/*.xml
    Nach dem Login kopieren
    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java7. UserMapper.xml

    <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
    Nach dem Login kopieren

    8.Service-SchichtSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    UserService-Schnittstelle schreiben: #🎜 🎜#
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
            private int id;
            private String name;
            private String pwd;
            private String perms;
    }
    Nach dem Login kopieren

    9. Schreiben Sie die Schnittstellenimplementierungsklasse UserServiceImpl

    @Repository
    @Mapper
    public interface UserMapper {
        public User  queryUserByName(String name);
     
    }
    Nach dem Login kopieren

    10. Testen Sie in ShiroSpringbootApplicationTests

    <?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>
    Nach dem Login kopieren

    # 🎜🎜#5. Anforderungsautorisierung implementieren

    1. Ändern Sie die ShiroConfig-Klasse

    2 #

    #🎜 🎜#

    3. Anmelden, um Autorisierung abzufangen, Test erfolgreich

    4. Autorisierungsmethode doGetAuthorizationInfo schreiben

    5. Autorisierungstest erfolgreich anfordern

    6. Shiro integriert Thymeleaf

    1. Abhängigkeiten importieren

    public interface UserService {
        public User queryUserByName(String name);
    }
    Nach dem Login kopieren

    2. ShiroDialect integrieren

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    3. index.html

    # 🎜🎜#So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    4. Test

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    5

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java# in der Authentifizierung 🎜🎜#

    6. Ändern Sie index.html

    So verwenden Sie das Apache Shiro-Sicherheitsframework in Java

    Das obige ist der detaillierte Inhalt vonSo verwenden Sie das Apache Shiro-Sicherheitsframework in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:yisu.com
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage