Shiro
O Apache Shiro é uma estrutura de autenticação e autorização leve. Comparado com a segurança da primavera, é simples e fácil de usar e tem alta flexibilidade. A própria Springboot fornece suporte à segurança, afinal, é sua própria coisa. O Springboot não integra Shiro por enquanto, então você precisa combinar você mesmo.
1. Adicione dependências
<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. Escreva a classe de configuração Shiro
pacote com.xbz.web.system.config; importar em.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.intercept.authorizationAttributesourCeadvisor; importar org.apache.shiro.spring.web.shirofilterfactorybean; importar org.apache.shiro.web.mgt.cookieMemberMemanager; importar org.apache.shiro.web.mgt.defaultwebecurityManager; importar org.apache.shiro.web.servlet.simplecookie; 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; importar java.util.arraylist; importar java.util.Collection; importar java.util.linkedhashmap; importar java.util.map; /*** Classe de configuração Shiro* Apacheshiro Core implementa o controle e a interceptação de permissão através do filtro, assim como o Springmvc usa o DispAchServlet para controlar a distribuição de solicitação. * Since it is using Filter, that is, filtering and permission verification through URL rules, we need to define a series of rules and access rights about URLs*/ @Configuration public class ShiroConfiguration { /** * DefaultAdvisorAutoProxyCreator, a bean of Spring, and Advisor decides which classes of methods to AOP proxy. */ @Bean @conditionalonMissingBean Public DefaultAdvisorAutoProxycreator DefaultAdvisoraUtoProxyCreator () {DefaultAdvisorautoProxycreator DefaultAap = new DefaultAdvisoraToUTOXYCRATRRATRATRORTOR (); defaultAap.setProxyTargetClass (true); return defaultAap; } /*** ShirofilterFactoryBean: para gerar shirofilter, manipule arquivos de recursos interceptando. * Mantém principalmente três itens de dados, SecurityManager, Filters, FilterChaIndEfinitionManager. * Nota: uma única configuração shirofilterfactorybean é ou relata um erro, porque, ao inicializar o shirofilterfactorybean, é necessário injetar: SecurityManager * * FilterChain Definição descrição * 1. Um URL pode configurar vários filtros, separados por comas * 2. Perms, papéis * */ @Bean public ShirofilterFactoryBean ShirofilterFactoryBean () {ShirofilterFactoryBean ShirofilterFactoryBean = new ShirofilterFactoryBean (); ShirofilterFactoryBean.SetSecurityManager (SecurityManager ()); ShirofilterFactoryBean.SetLoginurl ("/login"); // não define a página login.jsp no diretório raiz do projeto da web ShirofilterFactoryBean.SetSUCCESSURL ("/index"); // A conexão com o salto após o login é bem -sucedida/slirofilterFactoryBean.SetUnuthorlorlorized; // Interceptador personalizado, configurações para vários filtros*// mapa <string, filtro> filters = new LinkedHashmap <> (); // logoutFilter logoutFilter = new LogoutFilter (); // Limite o número de números on -line da mesma conta ao mesmo tempo. ou assinatura única, etc. // logoutFilter.SetRredirecTurl ("/login"); // filters.put ("logout", nulo); // shirofilterfactorybean.setFilters (filtros); Mapa <string, string> filterChainndefinitionMap = new LinkedHashMap <> (); // filterChainDefinitionManager deve ser um LinkedHashmap, pois deve garantir que o FilterCHAINDefinitionMap.put ("/css/**", "anon"); // Os recursos estáticos não exigem permissões, se houver arquivos em outros diretórios (como JS, IMG, etc.) e FilterChaIndefinitionMap.put ("/", "anon"); filterChainndefinitionMap.put ("/login", "anon"); // Configure a parte do URL filterChainndefinitionMap.put ("/logout", "logout"); filterChainndefinitionMap.put ("/user/**", "authc, papéis [role_user]"); // O usuário é uma função Role_User a acessar. A função do usuário controla o comportamento do usuário. filterChainndefinitionMap.put ("/events/**", "authc, papéis [role_admin]"); // filterChainndefinitionMap.put ("/user/edit/**", "authc, perms [usuário: edit]"); // Para teste, o valor morto é corrigido e também pode ser lido no banco de dados ou em outras configurações. Aqui, as permissões são usadas para controlar o filterCHAINDeFinitionMap.put ("/**", "authc"); // recursos que precisam ser conectados, geralmente colocados /** no fundo ShirofilterFactoryBean.setFilterChaindefinitionMap (filtrhainndefinitionMap); Retornar ShirofilterFactoryBean; } // Cookies e sessão da região // ========================== GANEREGEM E GERENCIAMENTO DE SESSÃO BEGN =========================== Private Static Final String Cookie_name = "RememberMe"; /** Gerenciamento de objetos de cookie*/public SimpleCookie RememberMeCookie () {// Este parâmetro é o nome do cookie, correspondendo ao nome da caixa de seleção no front end = RememberMe SimpleCookie SimpleCookie = new SimpleCookie (cookie_name); SimpleCookie.setMaxage (604800); // Lembre -se de que meu cookie entra em vigor por 7 dias e a unidade é retornada simplificada; } / ** Objeto de gerenciamento de cookies: lembre -me de função* / public brookieMemberMemanager Rememanger () {cookieMemberMemanager brokieMememberMemanager = new KrokieMemManger (); brookieMemberMemanager.Setcookie (lembre -se de MECOOKIE ()); brookieMemberMemanager.SetCipherkey (base64.Decode ("3avvhmflus0kta3kprsdag ==")); // Lembre -se a chave de criptografia de criptografia de cookie sugere que cada item é diferente o padrão de algoritmo AES (128 256 512) } @Bean sessionDao sessionDao () {return new MemorySessionDao (); } @Bean Public SessionManager sessionManager () {defaultWebSessionManager sessionManager = new DefaultWebSessionManager (); Coleção <SessionListener> ouvintes = new ArrayList <> (); ouvintes.add (new BdsSessionListener ()); sessionManager.SetSessionListeners (ouvintes); sessionManager.SetSessionDao (sessionDao ()); retorno sessionmanager; } // ====================== CONTRES E GERENCIAMENTO DE SESSÃO END ======================= /Endregion /*** SecurityManager: Gerenciador de transações de segurança principal, gerenciamento de permissão* Esta classe combina login, login, permissões e processamento de sessões. É uma classe relativamente importante. */ @Bean (name = "SecurityManager") public DefaultWebUsCurityManager SecurityManager () {DefaultWebSecurityManager SecurityManager = new DefaultWeburityManager (); SecurityManager.SetRealM (Shirorealm ()); SecurityManager.SetCachemanager (ehcachemanager ()); ///// Cache de informações sobre autorização/autenticação do usuário, usando o ehcache cache // gerenciamento de sessão personalizada usa o Redis SecurityManager.SetSessionManager (sessionManager ()); // injetar lembre -se do meu gerente; SecurityManager.SetRememberMemanager (RECKMEMANAGER ()); Retornar SecurityManager; } /** * Shirorealm, esta é uma classe de autenticação personalizada, herdada da AutorizeRealm, * responsável pela autenticação do usuário e processamento de permissão, você pode consultar a implementação do JDBCrealm. */ @Bean @Dependson ("LifeCycleBeanPostProcessor") public Shirorealm Shirorealm (CredentialSmatcher Matcher) {shirorealm realm = new Shirorealm (); RealM.SetCredentialSmatcher (Matcher); // Verificação de senha implementos de retorno reino; } /*** ehcachemanager, Cachemanager* Depois que o usuário efetua login com sucesso, armazenam em cache as informações e as informações de permissão do usuário e, em seguida, sempre que o usuário solicita, coloque -o na sessão do usuário. Se este feijão não estiver definido, o banco de dados será consultado uma vez para cada solicitação. */ @Bean @Dependson ("LifeCycleBeanPostProcessor") public Ehcachemanager Ehcachemanager () {Ehcachemanager em = new Ehcachemanager (); em.SetCachemanageRerConfigFile ("ClassPath: config/ehcache.xml"); // caminho do arquivo de configuração Retornar EM; } /** * LifeCycleBeanPostProcessor, esta é uma subclasse de DestructioneBeanPostProcessor, * é responsável pelo ciclo de vida de org.apache.shiro.util.initializable Bean. * é principalmente uma subclasse da classe AuthorizingRealm, bem como a classe Ehcachemanager. */ @Bean (name = "LifeCycleBeanPostProcessor") Public LifecycleBeanPostProcessor LifeCycleBeanPostProcessor () {return new LifeCycleBeanPostProcessor (); } /** * HashedCredentialSmatcher, esta classe é para codificar a senha, * impedindo que as senhas sejam armazenadas claramente no banco de dados. Of course, when logging in to authentication, * This class is also responsible for encoding the passwords entered in the form* Processing authentication matching processor: If customization requires the inheritance of HashedCredentialsMatcher */ @Bean(name = "hashedCredentialsMatcher") public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher credencialsmatcher = new HashedCredentialSmatcher (); Credencialsmatcher.SethashalGorithMName ("md5"); // Especifique o método de criptografia e você também pode adicionar o cache aqui. Quando o usuário efetua login mais de cinco erros de login, o usuário está bloqueado. O usuário é proibido de tentar fazer login constantemente no CredentialSmatcher.Sethashiterations (2); credenciaissmatcher.setStoredCredentialShexEncoded (true); Retornar CredencialsMatcher; } /** * AuthorizationAttributesourCeadVisor, a classe de consultor implementada em Shiro, * use aOpalliaCeannotações que consome a meteorização internamente para interceptar métodos com as anotações a seguir. */ @Bean Public AuthorizationAttributesourCeadVisor AuthorizationAttributesOrCeadvisor () {AuthorizationAttributesourCeadVisor Advisor = new AuthorizationAttributesourCeadvisor (); Advisor.SetSecurityManager (SecurityManager ()); consultor de retorno; } // @Bean public Shirodialect Shirodialect () {return New Shirodialect (); }} 3. Personalize a classe de verificação do reino
pacote com.yiyun.web.system.config; importar com.yiyun.dao.master.userdao; importação 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; importar java.util.*; / *** Obtenha a função do usuário e as informações de permissão*/ classe pública Shirorealm estende AuthorizingRealM {// geralmente, o que está escrito aqui é o Servic @AUTOWIRED PRIVADO UserDAPAPPERAPER; @Autowired Private MenUservice MenUservice; /*** Autenticação de login em geral, após o login, o usuário atual recebe permissões. Esta etapa é baseada no DogetauthenticationInfo. Somente após as informações do usuário você pode determinar se deve autorizar o usuário com base nas informações de função e autorização do usuário. Portanto, funções e permissões aqui estão as duas principais base de julgamento para o usuário * @param autenticationToken * @return * @throws autenticationException */ @Override AuthenticationInfo DogetAtHenticationInFo (Authentication AuthenticationToken) AuthenticationException {USERNAMEPASTENKENKENKENKENKENTENCOKEN = AuthEsticationException) Userdo user = userMApper.findbyName (token.getUserName ()); // Verifique se existe esse usuário se (usuário! = Null) {// se houver, armazene esse usuário nas informações de autenticação de login e não há necessidade de comparar a senha. Shiro executará a comparação e a verificação de senha para nós listar <urole> rlist = uroledao.findRoleByuid (user.getId ()); // obtenha a lista de função do usuário <uperMission> plist = uperMissionDao.findpermissionByuid (user.getId ()); List <String> permissionstrlist = new ArrayList <String> (); /// Coleção de permissão do usuário para (função de urole: rlist) {rolestlist.add (role.getName ()); } para (UperMission UperMission: Plist) {PerminsStrlist.add (UPERMISMISS.GETNAME ()); } user.setRolestlist (rolestlist); user.SetPerMinsStrList (PerminsStrlist); Sessão session = securityUtils.getSubject (). GetSession (); session.setAttribute ("Usuário", usuário); // Se for bem -sucedido, coloque -o na sessão // se existir, armazenar esse usuário nas informações de autenticação de login e você não precisará comparar sua senha. Shiro executará a verificação de comparação de senha para nós. Retornar novo SimpleAuthenticationInfo (usuário, user.getpassword (), getName ()); } retornar nulo; } / *** Autenticação de permissão* Obtenha as informações de permissão do usuário, que devem fazer julgamentos para a próxima etapa da autorização, para obter a função do usuário atual e as informações de permissão de propriedade dessas funções* @param PrincipalCollection* @RETURN* / @Override AutorizationInfo DogetaThorizationInfO (diretor -diretorcollollcollection* / @Override Autorizaçãoinfo DogetaThorizationInFo (Ministro Ministro (@return* / @Override AuthorizationInfo DogeTauthorizationInFo (Ministro Principal* é equivalente a (string) principalcollection.FromRealM (getName ()). Iterator (). Next (); // string loginName = (String) super.getAVALABLABLEPRINCIPAL (principalcollection); Userdo user = (userdo) principalcollection.getPrimaryPrincipal (); // // Vá para o banco de dados para verificar se esse objeto está presente // usuário do usuário = null; // em projetos reais, você pode armazenar em cache de acordo com a situação real. Caso contrário, o próprio Shiro tem um mecanismo de intervalo de tempo e não executará o método repetidamente dentro de 2 minutos // user = userMApper.findbyName (LoginName); if (user! = null) {// Informações de informação de permissão Informações do objeto, são usadas para armazenar todas as funções (função) e permissões (permissão) do usuário encontrado simplificação simplorizationInfo info = new SimpleAuthorizationInfo (); // coleta de função do usuário info.addroles (user.getRolestlist ()); // coleta de permissão do usuário info.addstringPermissions (user.getPerMinsStrlist ()); retornar informações; } // retorna nulo, ele fará com que qualquer usuário acesse a solicitação interceptada para pular automaticamente para o endereço especificado pelo UNAuthorizedurl; }}4. Finalmente, dê uma olhada no arquivo de configuração do ehcache
<? xml versão = "1.0" coding = "utf-8"?> <ehcache xmlns: xsi = "http://www.w3.org/2001/xmlschema-innstance" xsi: nonamesChemalocation = "htttp:/ehche <DiskStore Path = "java.io.tmpdir /tmp_ehcache" /> <!- Nome: Nome do cache. MaxElementsInMemory: Número máximo de caches maxElementsOndisk: Número máximo de caches para disco rígido. Eterno: se o objeto é permanentemente válido, uma vez definido, o tempo limite não funcionará. OverflowTodisk: Se deve salvar em disco, TimeToidleSeconds: define o tempo de marcha lenta permitida (unidade: segundos) do objeto antes de expirar. Usado apenas se o eternal = objeto falso não for permanentemente válido, atributo opcional, o valor padrão é 0, o que significa que o tempo de marcha lenta é infinita. TimetoliveSeconds: define a hora (unidade: segundos) do objeto antes de expirar. O tempo máximo é entre o tempo de criação e o tempo de falha. Somente usado se o eterno = objeto falso não for permanentemente válido, o padrão é 0., o que significa que o tempo de sobrevivência do objeto é infinito. DiskPersistent: se o armazenamento de disco persiste entre os reinicializações da máquina virtual. O valor padrão é falso. DISKSPOOLBUFFERSIZEMB: Este parâmetro define o tamanho do cache do DiskStore (cache de disco). O padrão é de 30 MB. Cada cache deve ter seu próprio buffer. DiskexpirythReadIntervalSeconds: o intervalo de tempo de falha de falha do disco, o padrão é de 120 segundos. MemoryStoreEvictionPolicy: Quando o limite MaxElementsInMemory for atingido, o ehcache limpa a memória de acordo com a política especificada. A política padrão é LRU (mais recentemente usada). Você pode defini -lo como FIFO (primeiro em, primeiro out) ou LFU (menos usado). ClearOnflush: se deve limpar quando a quantidade de memória é máxima. MemoryStoreEvictionPolicy: três estratégias de limpeza para o ehcache; FIFO, primeiro a sair, este é o mais familiar para todos, primeiro a sair. A LFU, menos frequentemente usada, é a estratégia usada no exemplo acima. Para ser franco, é para dizer que foi o menos usado de todos os tempos. Como mencionado acima, o elemento em cache possui um atributo de acerto e o menor valor de acerto será limpo do cache. LRU, menos usado recentemente, o elemento em cache tem um registro de data e hora. Quando a capacidade do cache estiver cheia e você precisa abrir espaço para armazenar em cache novos elementos, o elemento com o tempo mais distante do elemento de cache existente será liberado do cache. -> <defaultCache eternal = "false" maxElementsInmemory = "1000" OverflowTodisk = "false" DiskPerSistent = "False" timeToidleSeconds = "0" timeToliveSeConds = "600" MemoryStoreEvictionPolicy = "LRU" /> <!-Login Cache Cache maxentrieslocalhheap = "2000" eternal = "false" timeToidleSeconds = "3600" timetoliveSeconds = "0" OverflowTodisk = "false" Statistics = "true"> </cache> </ehcache>
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.