Shiro
Apache Shiro es un marco liviano de autenticación y autorización. En comparación con la seguridad de la primavera, es simple y fácil de usar y tiene una alta flexibilidad. SpringBoot en sí proporciona soporte para la seguridad, después de todo, es lo suyo. Springboot no integra a Shiro por el momento, por lo que debes igualarlo tú mismo.
1. Agregar dependencias
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.5</version> </dependency>
2. Escribe la clase de configuración de Shiro
paquete com.xbz.web.system.config; importar a.pollux.thymeleaf.shiro.dialect.shirodialect; importar org.apache.shiro.authc.credential.credentialsmatcher; importar org.apache.shiro.authc.credential.hashedcredentialsmatcher; importar org.apache.shiro.cache.ehcache.ehcachemanager; importar org.apache.shiro.codec.base64; importar org.apache.shiro.session.sessionListener; importar org.apache.shiro.session.mgt.sessionManager; importar org.apache.shiro.session.mgt.eis.memorysessiondao; importar org.apache.shiro.session.mgt.eis.sessiondao; 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.cookierememberManager; importar org.apache.shiro.web.mgt.defaultwebsecurityManager; importar org.apache.shiro.web.servlet.simprookie; importar org.apache.shiro.web.session.mgt.defaultWebSessionManager; importar org.springframework.aop.framework.autoproxy.defaultadvisorautoproxycreator; importar org.springframework.boot.autoconfigure.condition.condition.conditionalonmissingbean; importar org.springframework.context.annotation.bean; importar org.springframework.context.annotation.configuration; importar org.springframework.context.annotation.dependson; import java.util.arrayList; import java.util.collection; import java.util.linkedhashmap; import java.util.map; /*** SHIRO CLASE DE CONFIGURACIÓN* Apacheshiro Core implementa el control de permiso e intercepción a través del filtro, al igual que SpringMVC utiliza la distribución de solicitudes de solicitud para controlar. * Dado que está utilizando el filtro, es decir, el filtrado y la verificación de permiso a través de las reglas de URL, necesitamos definir una serie de reglas y derechos de acceso sobre las URL* / @Configuration, la clase pública Shiroconfiguration { / *** DefaultAdVisoraUtoProxyCreator, un frijol de primavera y asesor decide qué clases de métodos a aplausos. */ @Bean @conditionAlonMissingBean Public DefaultAdVisoraUtOproxyCreator DefaultAdVisorauToProxyCreator () {defaultAdVisoraUtOproxyCreator Defaultaap = new DefaultAdVisoraUtoProxyCreator (); DefaultAap.SetProxyTargetClass (true); devolver defaultAAP; } /*** shirofilterFactoryBean: para generar shirofilter, maneje la interceptación de archivos de recursos. * Mantiene principalmente tres elementos de datos, SecurityManager, Filters, FilterChainDefinitionManager. * Nota: Una sola configuración de ShiroFilterFactoryBean es o informa un error, porque al inicializar ShirOfilterFactoryBean, es necesario inyectar: SecurityManager * * FilterChain Definición Descripción * 1. Una URL puede configurar múltiples filtros, separados por Commas * 2. Cuando se establecen múltiples filtros, todos los que están verificados y se consideran y se consideran que se consideran * 3. Algunos filtros pueden especificarse, tal como se especifican los filtros, como se pueden ver, y se consideran los pastros, y se consideran los parámetros, y se consideran que algunos filtros se especifican. */ @Bean public shirofilterFactoryBean shirofilterFactoryBean () {shirofilterFactoryBean shirofilterFactoryBean = new shirofilterFactoryBean (); shirofilterFactoryBean.SetSecurityManager (SecurityManager ()); shirofilterFactoryBean.setLoginUrl ("/login"); // no establezca la página Login.jsp en el directorio raíz del proyecto web shirofilterFactoryBean.setSuccessUrl ("/index"); // La conexión para saltar después de login es exitoso shirofilteryBean.setUtauthorizedurl ("/403"); // Interceptor personalizado, Configuración para múltiples filtros*// Map <String, Filter> Filters = new LinkedHashMap <> (); // logroutfilter logroutFilter = new ShougeutFilter (); // Limite el número de números en línea de la misma cuenta al mismo tiempo. o inicio de sesión único, etc. // logroutfilter.setRedirectUrl ("/login"); // filters.put ("logrout", nulo); // shirofilterFactoryBean.setFilters (filtros); MAP <String, String> FilterChainDefinitionMap = new LinkedHashMap <> (); // FilterChainDefinitionManager debe ser un Linkedhashmap porque debe garantizar FilterChainDefinitionMap.put ordenado ordenado ("/css/**", "anon"); // Los recursos estáticos no requieren permisos, si hay archivos en otros directorios (como JS, IMG, etc.) y FilterChainDefinitionMap.put ("/", "anon"); filterChainDefinitionMap.put ("/login", "anon"); // Configure la parte de URL FilterChainDefinitionMap.put ("/logrout", "logrout"); FilterChainDefinitionMap.put ("/user/**", "authc, roles [role_user]"); // El usuario es un rol de role_user para acceder. El rol de usuario controla el comportamiento del usuario. FilterChainDefinitionMap.put ("/events/**", "authc, roles [role_admin]"); // FilterChainDefinitionMap.put ("/User/Edit/**", "Authc, Perms [User: Edit]"); // Para las pruebas, el valor muerto es fijo y también se puede leer desde la base de datos u otras configuraciones. Aquí, los permisos se utilizan para controlar FilterChainDefinitionMap.put ("/**", "Authc"); // Recursos que deben registrarse, generalmente poner /** en el fondo ShirofilterFactoryBean.setFilterChainDefinitionMap (FilterChainDefinitionMap); return shirofilterfactorybean; } // cookies de región y sesión // ========================================== COKIE Y SESIÓN Gestión de sesiones ======================== String Final String Final String_Name = "Recordme"; /** Gestión de objetos de cookie*/public SimpleCookie RememberMecookie () {// Este parámetro es el nombre de la cookie, correspondiente al nombre de la casilla de verificación en el front -end = RememberMe simplecookie simplecookie = nuevo simplecookie (cookie_name); SimpleCookie.SetMaxage (604800); // Recuerda que mi cookie entra en vigencia durante 7 días, y la unidad se devuelve SimpleCookie; } / ** Objeto de gestión de cookies: Recuerde la función* / public CookierememberMemanager RememberMemanager () {CookierememberMeManager CookierememberMemanager = new CookierememberManager (); CookierememberMemanager.setcookie (RememberMecookie ()); CookierememberMemanager.setCiPherkey (base64.Decode ("3AVVHMFLU0KTA3KPRSDAG ==")); // La clave de cifrado de recuerdo de cookie sugiere que cada elemento es diferente longitud de tecla de algoritmo AES predeterminado (128 256 512 bits) return CookiermemberMemanager; } @Bean Sessiondao SessionDao () {return New MemorySessionDao (); } @Bean Public SessionManager SessionManager () {defaultWebSessionManager sessionManager = new DefaultWebSessionManager (); Colección <sessionListener> oyentes = new ArrayList <> (); oyentes.add (new bdsessionListener ()); SessionManager.SetSessionListeners (oyentes); SessionManager.SetSessionDao (SessionDao ()); Return SessionManager; } // ===================== Cookies y gestión de sesiones Fin ========================= /Endregion /*** SecurityManager: Manager de transacciones de seguridad central, Gestión de permisos* Esta clase combina registro, registro, permisos y procesamiento de sesiones. Es una clase relativamente importante. */ @Bean (name = "SecurityManager") Public DefaultWebSecurityManager SecurityManager () {defaultWebSecurityManager SecurityManager = new DefaultWebSecurityManager (); SecurityManager.SetRealm (shirorealm ()); SecurityManager.SetCachemanager (ehcachemanager ()); ///// Cache de información de autorización/autenticación de usuario, utilizando Ehcache Cache // la administración de sesión personalizada utiliza Redis SecurityManager.SetSessionManager (SessionManager ()); // inyectar recuerde a mi gerente; SecurityManager.SetRememberManager (RememberMemanager ()); return SecurityManager; } /** * shirorealm, esta es una clase de autenticación personalizada, heredada de autorizar Realm, * responsable de la autenticación del usuario y el procesamiento de permisos, puede consultar la implementación de JDBCrealm. */ @Bean @dependson ("LifeCycleBeanPostProcessor") public shirorealm shirorealm (credentialsmatcher matcher) {shirorealm reasm = new shirorealm (); RealM.SetCredentialSmatcher (Matcher); // La verificación de contraseña implementa return realm; } /*** Ehcachemanager, Cachemanager* Después de que el usuario inicia sesión con éxito, almacena la información del usuario y la información de permiso, y luego cada vez que el usuario solicita, lo ponga en la sesión del usuario. Si este bean no está configurado, la base de datos se consultará una vez para cada solicitud. */ @Bean @dependson ("LifeCycleBeanPostProcessor") public ehcachemanager ehcachemanager () {ehcachemanager em = new ehcachemanager (); EM.SetCachemanagerConfigFile ("Classpath: config/ehcache.xml"); // La ruta del archivo de configuración return EM; } /** * LifeCycleBeanPostProcessor, esta es una subclase de destrucciónwareBeanPostProcessor, * es responsable del ciclo de vida de org.apache.shiro.util.initializable tipo bean. * Es principalmente una subclase de la clase AuthorizingRealm, así como la clase Ehcachemanager. */ @Bean (name = "lifecycleBeanPostProcessor") public lifecycleBeanPostProcessor LifecycleBeanPostProcessor () {return New LifeCycleBeanPostProcessor (); } /** * HashedCredentialSmatcher, esta clase es para codificar la contraseña, * evitando que las contraseñas se almacenen claramente en la base de datos. Por supuesto, al iniciar sesión en la autenticación, * Esta clase también es responsable de codificar las contraseñas ingresadas en el Formulario * Procesador de coincidencia de autenticación de procesamiento: si la personalización requiere la herencia de HashedCredCredentSmatcher */ @Bean (name = "HashedCredCedCredentSeNentialSmatCeSmatnentSmatCeReSmatCeSmatcherSmatcherSmatcherMatcherSmattersmatcher). HashedCredentialSmatcher (); credencialsmatcher.sethashalgorithmname ("md5"); // Especifique el método de cifrado, y también puede agregar el caché aquí. Cuando el usuario inicia sesión en más de cinco errores de inicio de sesión, el usuario está bloqueado. Se le prohíbe al usuario intentar constantemente iniciar sesión CredentialSmatcher.SethashIterations (2); CredentialSmatcher.SetStoredCredentialShexEncoded (true); Return CredentialSmatcher; } /** * AutorizationAttributeSourCeAdVisor, la clase de asesor implementada en Shiro, * use aOpallianceanNotationsAuthorizingMethodinterceptor internamente para interceptar métodos con las siguientes anotaciones. */ @Bean Public AuthorizationAttributeSourCeAdVisor AuthorizationAttributeSourCeadVisor () {AuthorizationAttributesOurCeAdVisor Advisor = New AuthorizationAttributesOurCeadVisor (); Advisor.SetSecurityManager (SecurityManager ()); asesor de devolución; } // @Bean public shirodialect shirodialect () {return new shirodialect (); }} 3. Personalizar la clase de verificación del reino
paquete com.yiyun.web.system.config; import com.yiyun.dao.master.userdao; import com.yiyun.domain.userdo; import com.yiyun.web.common.utils.shiroutils; import com.yiyun.web.system.service.menuservice; importar org.apache.shiro.securityUtils; importar org.apache.shiro.authc.*; importar org.apache.shiro.authz.authorizationInfo; importar org.apache.shiro.authz.simpleAuthorizationInfo; importar org.apache.shiro.realm.authorizingRealm; importar org.apache.shiro.session.session; importar org.apache.shiro.subject.principalCollection; importar org.springframework.beans.factory.annotation.aUtowired; import java.util.*; / *** Obtenga información de usuarios y permiso*/ clase public shirorealm extiende autorizingRealm {// En general, lo que se escribe aquí es servic @autewired userDao Usermapper; @Autowired Menuservicio privado Menuservicio; /*** Autenticación de inicio de sesión En términos generales, después de iniciar sesión, se les otorga permisos al usuario actual. Este paso se basa en DogetAuthenticationInfo. Solo después de la información del usuario puede determinar si autorizar al usuario en función del rol del usuario y la información de autorización. Por lo tanto, los roles y los permisos aquí son la base de dos juicios clave para el usuario * @param autenticación a lakoken * @return * @throws autenticaciónxception */ @Override autenticación protegidainfo dogetAuthenticationInfo (AuthenticationToken AuthenticationToken) Lanza AuthenticationException {usernamepasswordTtOW Userdo user = usermapper.findbyName (token.getUsername ()); // Compruebe si hay este usuario if (user! = Null) {// Si hay, almacene este usuario en la información de autenticación de inicio de sesión, y no hay necesidad de comparar la contraseña usted mismo. Shiro realizará la comparación y verificación de contraseñas para la lista de EE. UU. <UROLE> rlist = uroledao.findrolebyUid (user.getId ()); // Obtenga la lista de roles de usuario <Permission> plist = upermissiondao.findpermissionsByuid (user.getId ()); // Obtener permiso de usuario de usuarios <String> RolestrList = NewRallist <StryList <StryList <String> () ()///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////USI List <String> PermissionStrlist = new ArrayList <String> (); /// colección de permisos del usuario para (urole rol: rlist) {rolestrList.add (role.getName ()); } para (Upermission Upermission: Plist) {PerminsStrlist.Add (UPERMISSION.GETNAME ()); } user.setRolestrList (rolestrList); user.setPerminSstrList (perminsstrlist); Sesión sesión = SecurityUtils.getSubject (). GetSession (); session.SetAttribute ("Usuario", usuario); // Si tiene éxito, póngalo en sesión // Si existe, almacene este usuario en la información de autenticación de inicio de sesión y no necesita comparar su contraseña usted mismo. Shiro realizará la verificación de comparación de contraseñas para nosotros. Devolver nuevo SimpleAuthenticationInfo (usuario, user.getPassword (), getName ()); } return null; } / *** Autenticación de permiso* Obtenga la información de permiso del usuario, que es hacer juicios para el siguiente paso de autorización, para obtener el rol del usuario actual y la información de permiso propiedad de estos roles* @param PrincipalCollection* @return* / @Override Protected AuthorizationFo DoGetAuthorizationInfo (COBLECTIVO DE CONTERECCIÓN (ENTERSECTIVE DE CONTERECHO) (// es equivalente a (String) principalCollection.FromRealM (getName ()). Iterator (). Next (); // String LoginName = (String) Super.getAVailablePrIpRipal (PrincipalCollection); Userdo user = (userDO) principalCollection.getPrimaryPrIripal (); // // vaya a la base de datos para verificar si este objeto está presente // user user = null; // En proyectos reales, puede almacenar en caché de acuerdo con la situación real. Si no lo hace, el propio Shiro tiene un mecanismo de intervalo de tiempo y no ejecutará el método repetidamente en 2 minutos // user = usermapper.findbyName (LoginName); if (user! = null) {// Información del objeto de información de permiso se utiliza para almacenar todos los roles (rol) y permisos (permiso) del usuario sencillo de simpligulación de usuarios en información = new SimpleAuthorizationInfo (); // Información de recopilación de roles del usuario. // Información de recopilación de permisos del usuario.addStringPermissions (user.getPerminSstrList ()); Información de retorno; } // return null, hará que cualquier usuario acceda a la solicitud interceptada para saltar automáticamente a la dirección especificada por UnauthorizedURL; }}4. Finalmente, eche un vistazo al archivo de configuración de Ehcache
<? xml versión = "1.0" encoding = "utf-8"?> <ehcache xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: nonamespaceschemalocatation = "http://ehcache.org/ehcache.xsd" <diskstore path = "java.io.tmpdir /tmp_ehcache" /> <!- nombre: nombre de caché. MaxelementsInMemory: Número máximo de cachés MaxElementSondisk: Número máximo de cachés para el disco duro. Eternal: si el objeto es permanentemente válido, una vez establecido, el tiempo de espera no funcionará. OverflowTodisk: si se debe guardar en el disco, Timetoidlesegundos: establece el tiempo de inactividad permitido (Unidad: segundos) del objeto antes de que expire. Utilizado solo si el objeto Eternal = False no es permanentemente válido, el atributo opcional, el valor predeterminado es 0, lo que significa que el tiempo de inactividad es infinito. TimetoliveSeconds: establece el tiempo (unidad: segundos) del objeto antes de que expire. El tiempo máximo es entre el tiempo de creación y el tiempo de falla. Solo se usa si el objeto Eternal = falso no es permanentemente válido, el valor predeterminado es 0., lo que significa que el tiempo de supervivencia del objeto es infinito. Diskpersistente: si la tienda de disco persiste entre los reinicios de la máquina virtual. El valor predeterminado es falso. DiskspoolBufferSizember: este parámetro establece el tamaño de la caché de la tienda de disco (caché de disco). El valor predeterminado es de 30 MB. Cada caché debe tener su propio búfer. DiskExpiryThreadIntervalSeconds: el intervalo de tiempo de ejecución del hilo de falla del disco, el valor predeterminado es de 120 segundos. MemoryStoreEvictionPolicy: cuando se alcanza el límite maxelementsInMemory, Ehcache limpiará la memoria de acuerdo con la política especificada. La política predeterminada es LRU (más recientemente utilizada). Puede configurarlo en FIFO (primero en, primero fuera) o LFU (menos utilizado). ClearOnflush: si borrar cuándo la cantidad de memoria es máxima. MemoryStoreEvictionPolicy: tres estrategias de compensación para Ehcache; FIFO, primero en primera salida, este es el más familiar para todos, primero en primera vez. LFU, menos utilizado con frecuencia, es la estrategia utilizada en el ejemplo anterior. Para ser franco, es decir que ha sido el menos utilizado. Como se mencionó anteriormente, el elemento en caché tiene un atributo de éxito, y el valor de éxito más bajo se eliminará del caché. LRU, menos usado recientemente, el elemento caché tiene una marca de tiempo. Cuando la capacidad de la caché está llena y debe dejar espacio para almacenar nuevos elementos, el elemento con el tiempo más lejano en el elemento de caché existente se borrará del caché. -> <defaultcache eternal = "false" maxelementsInmemory = "1000" overflowTodisk = "false" diskpersistent = "false" timetoidleseConds = "0" timetoliveSeconds = "600" MemorySteeVictionPolicy = "LRU" /> <! MaxEnriesLocalHeap = "2000" Eternal = "False" TimetoidleseConds = "3600" TimetoliveSeconds = "0" OverflowTodisk = "False" Estadísticas = "True"> </cache> </ehcache>
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.