Que es shiro
Shiro es un marco de permiso de código abierto para la plataforma Java para la autorización de autenticación y acceso. Específicamente, se cumple el soporte para los siguientes elementos:
P: ¿Soporte para el grupo?
R: Shiro no admite la configuración de permisos para grupos de forma predeterminada.
P: ¿Puede satisfacer las necesidades de la asignación de roles para los grupos?
R: Extender el reino puede admitir la asignación de roles a los grupos, lo que en realidad es asignar permisos a todos los usuarios bajo el grupo.
P: ¿Soporte para permisos de datos? Definido en un sistema comercial?
R: SHIRO solo implementa el control sobre los permisos de operación, que se utiliza para ocultar o mostrar los elementos de control front-end y verificar los permisos de acceso de recursos. Los permisos de datos están estrechamente relacionados con necesidades comerciales específicas, y Shiro no puede controlar los permisos de datos.
P: ¿Asignación de permiso dinámico?
R: Extienda org.apache.shiro.realm.realm para admitir la asignación de permiso dinámico.
P: ¿Integrar con la primavera?
R: Puede admitir la integración con la primavera, y Shiro también admite etiquetas JSP.
En el blog anterior, hablamos sobre las dos características, autenticación y autorización más importantes de Shiro. El inicio de sesión único también es parte de la autenticación. Por defecto, Shiro ha implementado la integración con CAS para nosotros, y estará bien si agregamos algunas configuraciones integradas.
1. Agregue el paquete Shiro-Cas
<
2. Agregar configuración de inicio de sesión único
Aquí, publiqué todas las configuraciones para una fácil referencia, y se han agregado instrucciones detalladas a la configuración.
paquete com.chhliu.springboot.shiro.config; import java.util.linkedhashmap; import java.util.map; import javax.servlet.filter; importar org.apache.shiro.cache.ehcache.ehcachemanager; importar org.apache.shiro.cas.casfilter; importar org.apache.shiro.cas.cassubjectFactory; importar org.apache.shiro.spring.lifecycleBeanPostProcessor; importar org.apache.shiro.spring.security.interceptor.authorizationAttributesurCeadVisor; importar org.apache.shiro.spring.web.shirofilterfactorybean; importar org.apache.shiro.web.mgt.defaultwebsecurityManager; importar org.jasig.cas.client.session.singleSignoutFilter; importar org.jasig.cas.client.session.singlesignouthttpsessionListener; importar org.springframework.aop.framework.autoproxy.defaultadvisorautoproxycreator; importar org.springframework.boot.web.servlet.filterregistrationBean; importar org.springframework.boot.web.servlet.servletListenerRregistrationBean; importar org.springframework.context.annotation.bean; importar org.springframework.context.annotation.configuration; importar org.springframework.context.annotation.dependson; importar org.springframework.core.ordered; importar org.springframework.core.annotation.order; importar org.springframework.web.filter.delegatingFilterProxy; /*** Configuración de Shiro** Apache Shiro Core se implementa a través del filtro, al igual que SpringMVC usa DispachServlet para controlarlo. Dado que usamos * Filtro, generalmente podemos adivinar que el filtrado y la verificación del permiso se realizan a través de reglas de URL, por lo que necesitamos definir una serie de reglas y derechos de acceso sobre las URL. * * @author chhliu */@configuration public class shiroconfiguration {// CAS Servidor Dirección Public Static String final Casserverurlprefix = "http://127.0.0.1"; // Dirección de página de inicio de sesión CAS Cadena final estática Casloginurl = Casserverurlprefix + "/login"; // Dirección de sesión de sesión de CAS Cadena final estática CASLOGOUTURL = CASSERVERURLPREFIX + "/LOGOUT"; // La dirección de servicio actual proporcionada por el proyecto a la cadena final de la estática pública del mundo exterior ShiroserverUrlprefix = "http://127.0.1.28:8080"; // Casfilter UrlPatnPatn Public Static Final String CasfilterUrlPattern = "/index"; // Dirección de inicio de sesión public Static Final String LoginUrl = Casloginurl + "? Servicio =" + ShiroserverUrlPrefix + CasfilterUrlPattern; // Dirección de sesión de cierre de sesión (Casserver habilita la función de salto de servicio, y debe habilitar cas.logout.followserviceReDirects = true en el archivo webapps/cas/web-inf/cas.properties) public static string final de logrouturl = caslogouturl+"? Servicio ="+loginurl; // Iniciar sesión dirección exitosa // cadena final estática pública LoginSuccessurl = "/index"; // Autenticación de permiso fallido Dirección de salto Cadena final estática final unutorizedURL = "/Error/403.html"; / ** *Instanciar SecurityManager, esta clase es la clase central de Shiro */ @@return */ @Bean Public DefaultWebSecurityManager SecurityManager () {DefaultWebSecurityManager SecurityManager = newWebSecurityManager (); SecurityManager.SetRealm (MyShirocAsrealm ()); // <!-Cache de información de autorización/autenticación de usuario, utilizando Ehcache Cache-> SecurityManager.SetCachemanager (getEhcachemanager ()); // Especificar SujetFactory. Si desea implementar la función RECRUDE ME de CAS, debe usar la siguiente cassubjectFactory y establecerla en SecurityManager SUMPLATY SEGURYMANAGER.SETSUBECTACTORY (nueva cassubjectFactory ()); return SecurityManager; } / *** Configurar caché* @return* / @bean public ehcachemanager getehcachemanager () {ehcachemanager em = new ehcachemanager (); EM.SetCachemanagerConfigFile ("ClassPath: config/ehcache-shiro.xml"); devolverlos; } /*** Configurar reino. Dado que estamos utilizando CasRealm, la función de inicio de sesión único se ha integrado * @param Cachemanager * @return */ @Bean public myshirorealm myshirocasrealm () {myshireRealm reaM = new myShirorealM (); // Dirección del servidor de inicio de sesión de CAS prefijo realm.setCasserverUrlPrefix (shiroconfiguration.casserverurlprefix); // Dirección de devolución de llamada del cliente, dirección de salto después de que el inicio de sesión sea exitoso (su propia dirección de servicio) RealM.SetCasservice (shiroconfiguration.shiroserverurlprefix + shiroconfiguration.casfilterurlpattern); // El rol predeterminado después del inicio de sesión es exitoso, aquí es predeterminado al rol de usuario Realm.SetDefaulTroles ("Usuario"); Reino de retorno; }/ ** * Registre el oyente de cierre de sesión único * @return */ @supesswarnings ({"rawtypes", "sin verificar"}) @bean @order (ordenado.highest_precedence) // La prioridad es más alta que el servicio público de CASSeRlistenerNeRegistrationBean < ServletListenerRregistrationBean (); bean.setListener (nuevo singleighttpsessionListener ()); bean.setEnabled (verdadero); Bean de regreso; } / ** * Registre el filtro de sesión único * @return * / @Bean public FilterRegistrationBean SingleSeGeutFilter () {FilterRegistrationBean Bean = new FilterRegistrationBean (); Bean.setName ("SingleSeGeutFilter"); Bean.setFilter (nuevo SingleSeGeutFilter ()); bean.addurlpatterns ("/*"); bean.setEnabled (verdadero); Bean de regreso; } / ** * Registre DelegatingFilterProxy (shiro) * / @Bean Public FilterRegistrationBean DelegatingFilterProxy () {FilterRegistrationBean FilterRegistration = new FilterRegistrationBean (); FilterRregistration.setFilter (nuevo delegatingFilterProxy ("shirofilter")); // Este valor es falso de forma predeterminada, lo que indica que el ciclo de vida es administrado por SpringApplicationContext. Establecer en True significa que el ServletContainer se gestiona mediante filtros. FilterRegistration.SetEnabled (verdadero); filterregistration.addurlpatterns ("/*"); return FilterRregistration; } / *** Esta clase puede asegurarse de que el método init o de destino del objeto shiro que implementa el org.apache.shiro.util.initializable interfaz se llama automáticamente,* sin especificar manualmente el método init-method o del método de destino* Nota: si esta clase se usa, no es necesario especificar manualmente el método de inicialización y el método de destrucción, de lo contrario, ocurrirá un error* @retratado @@return* "LifeCycleBeanPostProcessor") público LifecycleBeBeanPostProcessor getLifecycleBeanPostProcessor () {return New LifeCycleBeanPostProcessor (); } /*** Las siguientes dos configuraciones se utilizan principalmente para habilitar el soporte de anotación SHIRO AOP. Usar el método proxy; Por lo tanto, debe habilitar el soporte de código; * @return */ @Bean @dependson ("LifeCycleBeanPostProcessor") Public DefaultAdVisorautoProxyCreator getDefaultAdVisoraUtOproxyCreator () {DefaultAdVisoraUtoProxyCreator Daap = New DefaultVisoraUtoProxycreator ();;; daap.setProxyTargetClass (verdadero); devolver daap; } / ** * @param SecurityManager * @return * / @Bean Public AuthorizationAttributeSourCeadVisor getAuthorizationAttributeSourCeadVisor (defaultWebSecurityManager SecurityManager) {AutorationAttributeSourCeAdVisor AutorizationArteurCeAdVisor = new AuthorizationAttributeUdVisor ();); AutorationAtTributesOurCeadVisor.SetSecurityManager (SecurityManager); devolver la autorizaciónattributesurCeadVisor; } / *** Filtro CAS* @return* / @Bean (name = "Casfilter") Public Casfilter getCasFilter () {casfilter casfilter = new CasFilter (); CasFilter.SetName ("Casfilter"); CasFilter.SetEnabled (verdadero); // La URL que salta después de que falló el inicio de sesión, es decir, Shiro ejecuta el método DoGetAuthenticationInfo de CasRealm para verificar Tiket Casfilter.SetFailureUrl (LoginUrl); // Eligimos abrir la página de inicio de sesión después de la autenticación fallida Casfilter.setLoginurl (loginurl); devolver Casfilter; } / ** * Crear e inicializar ShirOfilter usando el modo de fábrica * @param SecurityManager * @param Casfilter * @return * / @Bean (name = "shirofilter") public shirofilteryBean getShirOfilterFactoryBean (defaultwebSecurityManager SecurityManager, Cassfilter Casfilter) ShirofilterFactoryBean (); // SecurityManager debe establecerse shirofilterFactoryBean.SetSecurityManager (SecurityManager); // Si no establece el valor predeterminado, encontrará automáticamente la página "/Login.jsp" en el directorio raíz del proyecto web shirofilterFactoryBean.setLoginUrl (loginurl); / * * La conexión a redirigirse después de iniciar sesión es exitosa. Si no está configurado, saltará a la URL anterior de forma predeterminada. * Por ejemplo, primero ingresó http: // localhost: 8080/userlist en el navegador, pero ahora el usuario no ha iniciado sesión, por lo que saltará a la página de inicio de sesión. Después de que se apruebe la autenticación de inicio de sesión, la página * saltará automáticamente al http: // localhost: 8080/UserList Page en lugar de la página de índice después del inicio de sesión exitoso. No se recomienda establecer este campo */ // shirofilterfactorybean.setsuccessurl (loginsuccessurl); // Establecer acceso no autorizado a la página ShirofilterFactoryBean.SetunauthorizedUrl (UnauthorizedURL); / * * Agregar Casfilter a Shirofilter. Tenga en cuenta que Casfilter debe colocarse frente a Shirofilter, * para asegurarse de que el programa ingrese la autenticación de un solo punto antes de ingresar a Shiro Iniciar sesión */ MAP <String, Filter> Filters = new LinkedHashMap <> (); filters.put ("casfilter", casfilter); // El inicio de sesión ha sido reemplazado por el inicio de sesión de un solo punto // filters.put ("logrout", logOutFilter ()); shirofilterFactoryBean.setFilters (filtros); LoadShiroFilterChain (shirofilterFactoryBean); return shirofilterfactorybean; } /*** Cargar reglas de control de permiso Shirofilter (lea desde la base de datos y luego configure), el objeto MyShirocAsRealm proporciona información de rol /permiso. DogetAuthorizationInfo Implementación. * This part of the rules will be placed in the database during production* @param shiroFilterFactoryBean */ private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean){ //////////////////////////////////////// The following rules are best configured in the configuration file. Note that the filter added here needs to be orderly, so use LinkedHashMap ///////////////////////////////////////////////// Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); FilterChainDefinitionMap.put (CasfilterUrlPattern, "Casfilter"); // 2. Solicitudes que no interceptan FilterChainDefinitionMap.put ("/css/**", "anon"); filterChainDefinitionMap.put ("/js/**", "anon"); filterChainDefinitionMap.put ("/login", "anon"); // Aquí, configure la página de cierre de sesión en anon, no el inicio de sesión, porque el cierre de sesión se procesa por un solo punto, y no necesita ser interceptado por FilterFilter FilterChainDefinitionMap.put ("/logrout", "anon"); FilterChainDefinitionMap.put ("/Error", "anon"); // 3. Solicitudes interceptadas (obtenga de la base de datos local o del Casserver (métodos remotos como WebService, HTTP, etc.), consulte dónde están configurados sus permisos de roles) FilterChainDefinitionMap.put ("/User", "Authc"); // Iniciar sesión requerido // 4. El inicio de sesión no intercepta FilterChainDefinitionMap.put ("/**", "Authc"); shirofilterFactoryBean.setFilterChainDefinitionMap (filtreChainDefinitionMap); }}Alguna referencia de configuración: http://shiro.apache.org/spring.html
3. Escribe reino
Dado que necesitamos integrar las funciones de inicio de sesión único, necesitamos integrar la clase CasRealm. Esta clase ha implementado las funciones de la autenticación de un solo punto para nosotros. Lo que debemos hacer es implementar las funciones de la parte de autorización. El código de ejemplo es el siguiente:
paquete com.chhliu.springboot.shiro.config; import javax.annotation.resource; importar org.apache.shiro.securityUtils; importar org.apache.shiro.authc.authenticationInfo; importar org.apache.shiro.authc.authenticationToken; importar org.apache.shiro.authz.authenticationInfo; importar org.apache.shiro.authz.simpleAuthorizationInfo; importar org.apache.shiro.cas.casrealm; importar org.apache.shiro.subject.principalCollection; import com.chhliu.springboot.shiro.mode.syspermission; import com.chhliu.springboot.shiro.mode.syspermission; import com.chhliu.springboot.shiro.mode.userinfo; import com.chhliu.springboot.shiro.service.userinfoservice; /*** Clase de núcleo de verificación de permiso; Dado que se utiliza un solo inicio de sesión, no es necesario autenticarse, solo se requiere autorización * * @author chhliu */ public class myshirealm extiende casrealm {@Resource userInfoservice userInfoservice; / *** 1. Autenticación de CAS, verificar la identidad del usuario* 2. Establezca la información básica del usuario en la sesión para facilitar el acceso* 3. Este método puede usar directamente el método de autenticación en CasRealm, que solo se usa como una prueba*/ @Override protegida Autenticación de autenticación de DoGetAuthenticationInfo (autenticación de la autenticación Token) {// Llame al método de autenticación en el método de autenticación parentada. Casrealm ha implementado un solo punto de autenticación para nosotros. AutenticationInfo authc = super.dogetauthenticationInfo (token); // Obtenga la cuenta iniciada. Después de que la autenticación CAS sea exitosa, la cuenta se guardará. String cuenta = (string) authc.getPrincipals (). GetPrimaryPrInsipal (); // Guardar información del usuario en la sesión para una fácil adquisición de programas. Aquí puede colocar la información del usuario consultada en función de la cuenta de inicio de sesión en la sesión SecurityUtils.getSubject (). GetSession (). SetAttribute ("No", cuenta); devolver authc; } /*** La devolución de llamada se realizará solo cuando este método llame a Hasrole y HaPermission. * * Información del permiso. (Autorización): 1. Si el usuario sale normalmente, el caché se borrará automáticamente; 2. Si el usuario sale anormalmente, el caché se borrará automáticamente; * 3. Si modificamos los permisos del usuario pero el usuario no se cierra al sistema, los permisos modificados no pueden entrar en vigencia de inmediato. (Debe implementarse manualmente; poner en servicio para la llamada) * Después de modificar el permiso, se llama al método en reino. El reino ha sido administrado por la primavera, por lo que la instancia del reino se obtiene de la primavera y se llama el método ClearCached; *: La autorización es el control de acceso autorizado, utilizado para autorizar la operación realizada por el usuario, demostrando si el usuario permite la operación actual, como acceder a un determinado enlace, un archivo de recursos, etc. * * @param principales * @return */ @Override AutorizationInfo DoGeTauthorizationInfo (principales de la principios) {System.out.Println ("Permission DogetorizationizationizationAtization Configuración-> myshirorealm.dogetautorizationInfo () "); SimpleAuthorizationInfo AuthorizationInfo = new SimpleAuthorizationInfo (); // Obtenga el nombre de usuario después del inicio de sesión único, también puede obtenerlo de la sesión, porque después de que la autenticación sea exitosa, el nombre de usuario se ha colocado en el nombre de usuario de sess String = (String) Super.getavailablePrincipal (principios); // principales.getPrimaryPrincipal (); Este método también puede obtener el nombre de usuario // obtener la información de rol y permiso del usuario basada en el nombre de usuario userInfo userInfo = userInfoservice.findByUsername (nombre de usuario); // Empaque el rol correspondiente y la información de permiso en AuthorizationInfo para (sysrole rol: userInfo.getRoleList ()) {autorizationInfo.addrole (role.getRole ()); para (sySpermission p: role.getPermissions ()) {autorizationInfo.AddStringPermission (p.getPermission ()); }} return AuthorizationInfo; }} ¡A continuación, podemos realizar pruebas de verificación!
Ingrese http: 127.0.1.28: 8080/userInfo/userlist en el navegador y encontraremos que saltará automáticamente a la página de inicio de sesión de un solo punto
Luego ingresamos el nombre de usuario y la contraseña y saltará automáticamente al HTTP: 127.0.1.28: 8080/UserInfo/UserList.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.