Java --- Marco Shiro

Capítulo 1 Introducción Descripción general

1.1 ¿Qué es Shiro?

        Apache Shiro es un marco de seguridad (permisos) de Java potente y fácil de usar. Shiro puede completar: autenticación, autorización, cifrado, gestión de sesiones, integración con la Web, almacenamiento en caché, etc. Con Shiro puede proteger rápida y fácilmente cualquier aplicación, desde la aplicación móvil más pequeña hasta las aplicaciones web y empresariales más grandes.

 1.2 ¿Por qué usar shiro?

        El panorama del framework ha cambiado considerablemente desde 2003, por lo que todavía hay muchos sistemas que utilizan Shiro en la actualidad. Esto es inseparable de las características de Shiro.

        Facilidad de uso: construir un marco de seguridad del sistema con Shiro es muy simple. Incluso si es tu primera vez, podrás dominarlo rápidamente.

        Integral: Shiro incluye las funciones requeridas por el marco de seguridad del sistema y es un "servicio integral" para satisfacer las necesidades de seguridad.

        Flexible: Shiro puede trabajar en cualquier entorno de aplicación. Aunque puede funcionar en entornos Web, EJB e IOC, no es necesario depender de ellos. Shiro tampoco impone ninguna especificación ni muchas dependencias.

        Sólido soporte web: Shiro tiene un excelente soporte para aplicaciones web, puede crear políticas de seguridad flexibles basadas en URL de aplicaciones y protocolos web (como REST) ​​y también proporciona un conjunto de bibliotecas JSP para controlar la salida de la página.

        Gran compatibilidad: los patrones de diseño de Shiro facilitan la integración con otros marcos y aplicaciones. Shiro se integra perfectamente con marcos como Spring, Grails, Wicket, Tapestry, Mule, Apache Camel, Vaadin y más.

1.3 Comparación entre Shiro y SpringSecurity

1. Spring Security se desarrolla en base a Spring. Si el proyecto utiliza Spring como base, es más conveniente cooperar con SpringSecurity para establecer permisos, pero Shiro debe integrarse con Spring para el desarrollo;

2. Spring Security tiene funciones más ricas que Shiro, como el mantenimiento de la seguridad;

3. Los recursos de la comunidad Spring Security son relativamente más ricos que los de Shiro;

4. Shiro es relativamente sencillo de configurar y usar, pero empezar con Spring Security es más complicado;

5. Shiro tiene pocas dependencias y no requiere ningún marco ni contenedor, puede ejecutar Spring Security de forma independiente y depende de los contenedores Spring;

6. Shiro no sólo se puede utilizar en la web, sino que también puede funcionar en cualquier entorno de aplicación. Quizás uno de los beneficios más importantes de Shiro cuando se trata de agrupar sesiones es que sus sesiones son independientes del contenedor.

1.4 ¿Qué funciones hay?


(1) Autenticación: autenticación de identidad/inicio de sesión, verifique si el usuario tiene la identidad correspondiente.

(2) Autorización: Autorización, es decir, verificación de permiso, para verificar si un usuario autenticado tiene un determinado permiso, es decir, para determinar si el usuario puede realizar alguna operación, como verificar si un usuario tiene un determinado rol. O verificación detallada de si un usuario tiene un determinado permiso sobre un determinado recurso.

(3) Gestión de sesión: La gestión de sesión significa que después de que un usuario inicia sesión, es una sesión. Antes de salir, toda su información está en la sesión, la sesión puede ser en un entorno JavaSE normal o en un entorno web.

(4) Criptografía: cifrado para proteger la seguridad de los datos, como que las contraseñas se cifren y se almacenen en la base de datos en lugar de almacenarse en texto sin cifrar.

(5) Soporte web: el soporte web se puede integrar fácilmente en el entorno web.

(6) Almacenamiento en caché: por ejemplo, después de que un usuario inicia sesión, no es necesario verificar su información de usuario y sus roles/permisos cada vez, lo que puede mejorar la eficiencia.

(7) Concurrencia: Shiro admite la verificación concurrente de aplicaciones de subprocesos múltiples, es decir, si inicia otro subproceso en un subproceso, los permisos se pueden propagar automáticamente.

(8) Pruebas: proporcionar soporte para pruebas.

(9) "Ejecutar como": permite que un usuario pretenda ser otro usuario (si lo permite).

(10) Recuérdame: Recuérdame, esta es una función muy común, es decir, después de iniciar sesión una vez, no es necesario que inicies sesión la próxima vez.

1.5 Arquitectura Shiro (externa)

imagen-20200729114702566

Mirando a Shiro desde afuera, es decir, viendo cómo usar Shiro para hacer las cosas desde la perspectiva de la aplicación.

Asunto: el objeto con el que interactúa directamente el código de la aplicación es el Asunto, lo que significa que el núcleo de la API externa de Shiro es el Asunto. El Asunto representa el "usuario" actual, que no es necesariamente una persona específica. Cualquier cosa que interactúe con la aplicación actual es un Asunto, como rastreadores web, robots, etc.; todas las interacciones con el Asunto se delegará al SecurityManager; el El sujeto es en realidad una fachada, SecurityManager es el ejecutor real

SecurityManager: Administrador de seguridad, es decir, todas las operaciones relacionadas con la seguridad interactuarán con SecurityManager, y este administra todos los Sujetos, se puede ver que es el núcleo de Shiro, y es responsable de interactuar con otros componentes de Shiro. equivalente al carácter DispatcherServlet en SpringMVC de

Realm: Shiro obtiene datos de seguridad (como usuarios, roles, permisos) de Realm, es decir, si SecurityManager desea verificar la identidad del usuario, necesita obtener el usuario correspondiente de Realm para compararlo y determinar si la identidad del usuario es legítimo; también necesita obtener la respuesta del usuario de Realm. Utilice el rol/permiso para verificar si el usuario puede realizar operaciones; Realm puede considerarse como una fuente de datos.

1.6 Arquitectura Shiro (interna)

imagen-20200729114720578

  • Asunto: Cualquier "usuario" que pueda interactuar con la aplicación.
  • SecurityManager: Equivalente al DispatcherServlet en SpringMVC; es el corazón de Shiro; todas las interacciones específicas se controlan a través de SecurityManager; gestiona todos los sujetos y es responsable de la autenticación, autorización, sesión y gestión de caché.
  • Autenticador: Responsable de la autenticación del Sujeto, es un punto de extensión y se puede personalizar, se puede utilizar la estrategia de autenticación (Estrategia de autenticación), es decir, ¿bajo qué circunstancias se pasa la autenticación del usuario?
  • Autorizador: Autorizador, es decir, controlador de acceso, utilizado para determinar si el sujeto tiene permiso para realizar las operaciones correspondientes, es decir, controla a qué funciones de la aplicación puede acceder el usuario.
  • Reino: Puede haber uno o más Reinos, que pueden considerarse como una fuente de datos de entidad segura, es decir, utilizados para obtener entidades seguras; puede ser una implementación JDBC, una implementación de memoria, etc.; proporcionada por el usuario; entonces generalmente se usa en aplicaciones y necesita implementar su propio Reino.
  • SessionManager: un componente que gestiona el ciclo de vida de la sesión; Shiro se puede utilizar no solo en el entorno web, sino también en entornos JavaSE normales.
  • CacheManager: controlador de caché para administrar cachés como usuarios, roles, permisos, etc.; debido a que estos datos rara vez cambian, colocarlos en el caché puede mejorar el rendimiento del acceso.
  • Criptografía: módulo de criptografía, Shiro mejora algunos componentes de cifrado comunes para el cifrado/descifrado de contraseñas.

Capítulo 2 autenticación de inicio de sesión de shiro

1.Crear base de datos
ESTABLECER NOMBRES utf8mb4;
ESTABLECER FOREIGN_KEY_CHECKS = 0 ;
--------------------------------------
-- Estructura de tabla para el usuario
--------------------------------------
SOLTAR TABLA SI EXISTE `usuario`;
CREAR TABLA `usuario` (
`uid` int ( 11 ) NO NULL AUTO_INCREMENT,
`uname` varchar ( 32 ) CONJUNTO DE CARACTERES utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` varchar ( 32 ) CONJUNTO DE CARACTERES utf8 COLLATE utf8_general_ci NOT NULL ,
`sex` varchar ( 2 ) CONJUNTO DE CARACTERES utf8 COLLATE utf8_general_ci DEFAULT NULL ,
`dirección` varchar ( 200 ) CONJUNTO DE CARACTERES utf8 COLLATE utf8_general_ci PREDETERMINADO
NULO ,
`estado` int ( 2 ) POR DEFECTO NULO ,
`salt` varchar ( 32 ) CONJUNTO DE CARACTERES utf8 COLLATE utf8_general_ci DEFAULT NULL ,
CLAVE PRIMARIA (`uid`) USANDO BTREE,
ÍNDICE ÚNICO `uname`(`uname`) USANDO BTREE
) MOTOR = InnoDB AUTO_INCREMENT = 4 CONJUNTO DE CARACTERES = utf8 COLLATE =
utf8_general_ci ROW_FORMAT = Dinámico;
--------------------------------------
-- Registros de usuario
--------------------------------------
INSERTAR EN VALORES `usuario` ( 1 , 'admin' , '727d8b2b4c59366d7ace58d4eda4cfee' , '' ,
' Luoyang, Henan ' , 1 , '9C2AB20283F9450389330033D64686DD' );
INSERTAR EN VALORES `usuario` ( 2 , 'zs' , '83f12ba7c4357b87167e240a22c15248' , ' man ' , ' kawa
Sur de Zhengzhou ' , 1 , '262F995823C94D1CAE7596B47E8AB657' );
seleccione * del usuario
2. Cree un proyecto web y configure SSM
Complete la escritura de la capa dao y la capa de servicio de la tabla de usuarios.
3. Cree MyShiroRealm y herede AuthorizingRealm
Nota: utilice la anotación @Component para la gestión de primavera
package com.chen.shiro;
import com.chen.bean.User;
import com.chen.service.IUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
4.在spring.xml中配置shiro管理器和自定义的Realm
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* token 里面是客户端发来的信息(包含输入的用户名 和 密码)
* 自定义Realm,通过mybatis查询数据库的密码和盐值,让shiro进行身份验证
*/
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
IUserService userService;
//shiro 进行授权操作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principals) {
return null;
}
//shiro 进行认证操作
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken
token) throws AuthenticationException {
//token 是主体传过来的身份令牌
//1 获取用户身份信息
String uname = token.getPrincipal().toString();
//2 调用业务层获取用户信息(数据库中)
User user = userService.findByUname(uname);
//3 判断并将数据完成封装
if(user!=null){
AuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(
token.getPrincipal(), //令牌身份信息对象
user.getPwd(), //用户数据库的密码
ByteSource.Util.bytes(user.getSalt().getBytes()), //加密时的
盐值
uname // 用户名
);
return authenticationInfo;
}
return null;
}
}

 4. Configure shiro manager y Realm personalizado en spring.xml

<!--=================shiro相关配置====================-->
<!--配置shiro进行校验时的加密规则-->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--加密规则-->
<property name="hashAlgorithmName" value="MD5" />
<!--是否加盐-->
<property name="hashSalted" value="true" />
<!--是否增加哈希算法进行散列-->
<!-- <property name="hashIterations" value="1024" />-->
</bean>
<!--配置自定义Realm-->
<bean id="myRealm" class="com.chen.shiro.MyRealm">
<property name="credentialsMatcher" ref="credentialsMatcher" />
</bean>
<!--配置安全管理器,使用自定义的Realm-->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--配置自定义的Realm-->
<property name="realm" ref="myRealm" />
</bean>
<!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 调用我们配置的权限管理器 -->
<property name="securityManager" ref="securityManager"/>
<!-- 配置拦截后我们的登录请求地址 -->
<property name="loginUrl" value="/loginUI"/>
<!-- 如果您请求的资源不再您的权限范围,则跳转到错误页面 -->
<property name="unauthorizedUrl" value="/error"/>
<!-- 权限配置
anon:任何人都可以访问; authc:必须是登录之后才能进行访问,不包括remember
me;
perms:指定过滤规则,可以自己拓展权限配置; roles:配置角色;
user:登录用户才可以访问,包含remember me; logout:退出
-->
<property name="filterChainDefinitions">
<value>
/=anon
/index = anon
/loginUI = anon
/login = anon
/WEB-INF/view/login.html = anon
/**/*.js=anon
/**/*.css=anon
/**=authc
/**=user
</value>
</property>
</bean>
Perfil de derechos
anon : cualquiera puede acceder;
authc : el acceso debe realizarse después de iniciar sesión, excluyendo recordarme ;
perms : especifique reglas de filtrado y podrá ampliar la configuración de permisos usted mismo;
roles : configurar roles;
usuario : Sólo los usuarios que hayan iniciado sesión pueden acceder, incluido recordarme ;
cerrar sesión : salir

5.Configurar el filtro shiro en web.xml

<!-- shiro配置 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filterclass>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

 6. Realice la autenticación Shiro en el controlador.

package com.chen.controller;

import com.chen.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
public class UserController {
    @Autowired
    UserService userService;

    @RequestMapping("/login")
    public String login(String uname, String pwd, HttpSession session) {
        System.out.println(uname+"------------------");
        //1 获取 Subject 对象
        Subject subject = SecurityUtils.getSubject();
//2 封装请求数据到 token 对象中
        AuthenticationToken token = new UsernamePasswordToken(uname, pwd);
//3 调用 login 方法进行登录认证
        try {
            //5.验证主体是否能够登录
            subject.login(token);
            session.setAttribute("user", token.getPrincipal().toString());
            return "main";
        } catch (UnknownAccountException e) {
            System.out.println("用户名不存在!");
            return "login";
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误!");
            return "login";
        } catch (AuthenticationException e) {
            System.out.println("认证失败,不知道出了什么问题");
            return "login";
        }
    }
}

Capítulo 3  La función recordarme de Shiro

Shiro proporciona la función RememberMe . Por ejemplo, cuando visitas algunos sitios web y cierras el navegador, aún puedes recordar quién eres cuando lo abres nuevamente la próxima vez. Puedes acceder a él sin iniciar sesión nuevamente la próxima vez que lo visites.
Por ejemplo: cuando no haya iniciado sesión, el acceso a la página de inicio /principal será interceptado y redirigido a la página de inicio de sesión. Después de iniciar sesión, podrás acceder normalmente
Pregunte acerca de la página de inicio de /main ; si se utiliza la función recordarme, se escribirá una cookie en el navegador . Si cierra el navegador, podrá acceder directamente a /main sin iniciar sesión .
Proceso básico
1. Primero seleccione Recordarme en la página de inicio de sesión e inicie sesión correctamente; si inicia sesión a través de un navegador, normalmente
La cookie de RememberMe se escribe en el cliente y se guarda;
2. Cierra el navegador y vuelve a abrirlo, verás que el navegador aún te recuerda;
3. Al acceder a un servidor web general, aún sabes quién eres y puedes acceder a él normalmente;
4. Sin embargo, si accedemos a la plataforma de comercio electrónico, si queremos verificar mi pedido o realizar el pago, aún necesitamos autenticarnos nuevamente.
autenticado para garantizar que el usuario actual sigue siendo usted.
1. Configure los ajustes de cookies y el administrador RememberMe en spring.xml

1. Configure los ajustes de cookies para la función Recordarme ;

2. Configurar el administrador de la función recordarme;
3. Haga referencia al administrador de la función recordarme en el administrador de seguridad;
4. Configure la configuración de filtrado de RememberMe en shiroFilter en el filtro ( /**=user )
<!--=================shiro相关配置====================-->
<!--配置shiro进行校验时的加密规则-->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--加密规则-->
<property name="hashAlgorithmName" value="MD5" />
<!--是否加盐-->
<property name="hashSalted" value="true" />
<!--是否增加哈希算法进行散列-->
<!-- <property name="hashIterations" value="1024" />-->
</bean>
<!--配置自定义Realm-->
<bean id="myRealm" class="com.chen.shiro.MyRealm">
<property name="credentialsMatcher" ref="credentialsMatcher" />
</bean>
<!--=================记住我功能相关配置====================-->
<!--记住我功能的cookie设置-->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!--设置cookie的属性名-->
<property name="name" value="rememberMe" />
<!--设置cookie存在根目录,可在同一应用服务器内共享-->
<property name="path" value="/" />
<!--通过JavaScript脚本将无法读取到Cookie信息,这样能有效的防止XSS攻击,让网站应用更
加安全-->
<property name="httpOnly" value="true" />
<!--设置cookie的失效时间为30天-->
<property name="maxAge" value="2592000" />
</bean>
<!--记住我功能的管理器配置-->
<bean id="rememberMeManager"
class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<!--引用cookie设置-->
<property name="cookie" ref="simpleCookie" />
<!--默认AES算法,设置cookie的加密算法,采用的是base64的加密-->
<property name="cipherKey" value="#
{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
</bean>
<!--配置安全管理器,使用自定义的Realm-->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--配置自定义的Realm-->
<property name="realm" ref="myRealm" />
<!--====引用rememberMe功能管理器====================-->
<property name="rememberMeManager" ref="rememberMeManager" />
</bean>
<!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 调用我们配置的权限管理器 -->
<property name="securityManager" ref="securityManager"/>
<!-- 配置拦截后我们的登录请求地址 -->
<property name="loginUrl" value="/loginUI"/>
<!-- 如果您请求的资源不再您的权限范围,则跳转到错误页面 -->
<property name="unauthorizedUrl" value="/error"/>
<!-- 权限配置 -->
<!-- 权限配置
anon:任何人都可以访问; authc:必须是登录之后才能进行访问,不包括remember
me;
perms:指定过滤规则,可以自己拓展权限配置; roles:配置角色;
user:登录用户才可以访问,包含remember me; logout:退出
-->
<property name="filterChainDefinitions">
<value>
/=anon
/index = anon
/loginUI = anon
/login = anon
/WEB-INF/view/login.html = anon
/**/*.js=anon
/**/*.css=anon
/**=authc
/**=user
</value>
</property>
</bean>
2. Agregue un botón de casilla de verificación Recordarme en la página y establezca el atributo de nombre en Recordarme.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<div id="content">
    <form class="form-horizontal" action="/login" method="post">
        <div class="form-group">
            <label for="uname" class="col-sm-2 control-label">帐号</label>
            <div class="col-sm-10">
                <input type="text" name="uname" class="form-control" id="uname"
                       placeholder="帐号">
            </div>
        </div>
        <div class="form-group">
            <label for="pwd" class="col-sm-2 control-label">密码</label>
            <div class="col-sm-10">
                <input type="password" name="pwd" class="form-control" id="pwd"
                       placeholder="密码">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <div class="checkbox">
                    <label>
                        <input type="checkbox" name="rerememberMe"> 记住我
                    </label>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" id="login" class="btn btn-primary">登录
                </button>
                <a href="/indexUI">去注册</a>
            </div>
        </div>
    </form>
</div>
</body>
</html>
3. Modifique el controlador o verifique si la función Recuérdame está marcada y agregue una marca Recuérdame durante la autenticación.
1. Configure el parámetro de solicitud de tipo booleano recordarme y establezca el valor predeterminado en falso ;
2. Al encapsular el token , agregue la etiqueta recordarMe ;

package com.chen.controller;

import com.chen.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
public class UserController {
    @Autowired
    UserService userService;

    @RequestMapping("/login")
    public String login(String uname, String pwd, @RequestParam(defaultValue = "false") boolean rerememberMe, HttpSession session) {
        System.out.println(uname+"------------------");
        //1 获取 Subject 对象
        Subject subject = SecurityUtils.getSubject();
//2 封装请求数据到 token 对象中
        AuthenticationToken token = new UsernamePasswordToken(uname, pwd,rerememberMe);
//3 调用 login 方法进行登录认证
        try {
            //5.验证主体是否能够登录
            subject.login(token);
            session.setAttribute("user", token.getPrincipal().toString());
            return "main";
        } catch (UnknownAccountException e) {
            System.out.println("用户名不存在!");
            return "login";
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误!");
            return "login";
        } catch (AuthenticationException e) {
            System.out.println("认证失败,不知道出了什么问题");
            return "login";
        }
    }
}
4. Pruebe la función recordarme
1. Si accede directamente a la página de inicio /principal sin iniciar sesión , shiro interceptará e irá a la página de inicio de sesión; después de iniciar sesión, podrá acceder a la página de inicio /principal normalmente ;
2. Si no marca Recordarme al iniciar sesión, cerrar el navegador y acceder a la página de inicio /principal seguirá interceptando la página de inicio de sesión;
3. Marque Recordarme al iniciar sesión, cierre el navegador y acceda a la página de inicio /principal para un acceso normal;

Capítulo 4 El cierre de sesión de Shiro

1. Establezca un enlace para cerrar sesión en la página de inicio.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>主页</title>
<body>
<img src="/img/index.jpg">
<a href="/logout">退出登录</a>
</body>
</html>
2. Busque el filtro shiro en el archivo de configuración spring.xml y configure la operación de cierre de sesión.
<property name="filterChainDefinitions">
<value>
/=anon
/index = anon
/loginUI = anon
/login = anon
/logout=logout
/WEB-INF/view/login.html = anon
/**/*.js=anon
/**/*.css=anon
/**=authc
/**=user
</value>
</property>

Capítulo 6  Autenticación de autorización de rol de Shiro

1. Diseñe dos hipervínculos en la página de inicio para simular la visualización de la administración de usuarios y la administración
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页</title>
</head>
<body>
<h2>内容页</h2>
<a href="/loginOut">退出登录</a>
<hr>
<ul>
    <li><a href="/user">用户管理</a></li>
    <li><a href="/system">系统管理</a></li>
</ul>
</body>
</html>
2. Utilice la anotación @RequiresRoles("roles") en el controlador para habilitar la verificación de roles para solicitudes
   @RequiresRoles("user")
    @RequestMapping("/user")
    public String user(){
        System.out.println("用户管理");
        return "userList";
    }
    @RequiresRoles("admin")
    @RequestMapping("/system")
    public String system(){
        System.out.println("系统管理");
        return "system";
    }
3. Habilite la compatibilidad con anotaciones shiro en springmvc.xml
Dado que las anotaciones shiro se configuran en el controlador , el soporte para anotaciones shiro debe configurarse en springmvc.xml ;
1. Configurar el procesador del ciclo de vida del frijol shiro.
2. Configurar la creación automática de agentes;
3. Habilite el soporte para anotaciones shiro

    <!--配置shiro bean生命周期处理器-->
    <bean id="lifecycleBeanPostProcessor"
          class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <!--配置自动创建代理-->
    <bean
            class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true" />
    </bean>
    <!-- 开启shiro注解的支持 -->
    <bean
            class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>
4. Se produce una excepción al acceder a dos hipervínculos en la página de inicio, lo que indica que la operación no tiene una función
El mensaje de error es el siguiente:
org.springframework.web.util.NestedServletException: procesamiento de solicitudes
fallido; La excepción anidada es org.apache.shiro.authz.UnauthorizedException:
El sujeto no tiene rol [admin]
5. Simule la autenticación de roles: en el método de autorización de la clase Realm personalizada , agregue manualmente un rol al usuario (luego use la base de datos para consultar si hay un rol) y luego verifique si el usuario puede acceder normalmente.
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principalCollection) {
System.out.println("授权方法被执行==============");
//创建角色和权限对象
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
//模拟添加角色
authorizationInfo.addRole("user");
//返回权限
return authorizationInfo;
}
...

Capítulo 7 autenticación de autorización de autoridad shiro

1. Diseñar operaciones de adición, eliminación, modificación y consulta de usuarios en la gestión de usuarios y simular la verificación de permisos, respectivamente.
<body>
<ul>
<li><a href="/user/add">添加用户</a></li>
<li><a href="/user/delete">删除用户</a></li>
<li><a href="/user/find">查看用户</a></li>
<li><a href="/user/revise">修改用户</a></li>
</ul>
</body>
2.La referencia de configuración de Shiro es la anterior.
3. Utilice la anotación @RequiresPermissions("permiso") en el controlador para habilitar la verificación de roles para las solicitudes.

    @RequiresPermissions("user:add")
    @RequestMapping("/user/add")
    @ResponseBody
    public String add(){
        System.out.println("用户添加操作");
        return "action user add...";
    }
    @RequiresPermissions("user:add")
    @RequestMapping("/user/delete")
    @ResponseBody
    public String delete(){
        System.out.println("用户删除操作");
        return "action user delete...";
    }
    @RequiresPermissions("user:find")
    @RequestMapping("/user/find")
    @ResponseBody
    public String find(){
        System.out.println("用户查看操作");
        return "action user find...";
    }
    @RequiresPermissions("user:revise")
    @RequestMapping("/user/revise")
    @ResponseBody
    public String revise(){
        System.out.println("用户修改操作");
        return "action user revise...";
    }
4. En el método de autorización de la clase Realm personalizada , agregue manualmente permisos al usuario (luego use la base de datos para verificar si hay permisos) y luego verifique si el acceso .
package com.chen.shior;

import com.chen.bean.User;
import com.chen.service.UserService;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 自定义Realm,通过mybatis查询教据库密码和盐值,让shiro进行身份验证
 */
@Component
public class MyShiroRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    //shiro 进行授权操作
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权方法被执行==============");
        //1.创建角色和权限对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        //2.1 获取用户登录
        String uname = principalCollection.getPrimaryPrincipal().toString();
        System.out.println("当前登录用户为:"+uname);
        if (uname.equals("admin")){
            //正常查询用户的角色(数据库使用set) 现在模拟赋予角色
            String role ="admin";
            authorizationInfo.addRole(role);
            authorizationInfo.addRole("user");

            //授予权限正常查询用户的权限,现在模拟赋予权限
            authorizationInfo.addStringPermission("user:add");
            authorizationInfo.addStringPermission("user:delete");
            authorizationInfo.addStringPermission("user:find");
            authorizationInfo.addStringPermission("user:revise");
            }else {
            authorizationInfo.addRole("user");
            authorizationInfo.addStringPermission("user:add");
            authorizationInfo.addStringPermission("user:find");
        }
        //返回权限
        return authorizationInfo;
    }

}
.......
5. Pruebe para ver si puede acceder a la página de administración de usuarios.
El permiso para agregar está configurado y puede acceder a él normalmente haciendo clic en Agregar usuario;
Al hacer clic en el usuario para eliminar se generará una excepción de la siguiente manera:
org.springframework.web.util.NestedServletException: procesamiento de solicitudes
fallido; La excepción anidada es org.apache.shiro.authz.UnauthorizedException:
El sujeto no tiene permiso [usuario: eliminar]

Supongo que te gusta

Origin blog.csdn.net/weixin_67224308/article/details/131522608
Recomendado
Clasificación