Before ssm framework stage, we learned some basic use shiro, when using shiro like this:
1. Configure shiro profile management using spring shiro
2. Edit the realm logged in, log on and implement methods within
3. In the controller layer username and password UsernamePasswordToken encapsulated into a token, and realizes login method, as shown:
At that time we will package token and sign-in method is written in the controller, but this is the wrong way to edit, re-learning shiro, a new understanding of shiro:
Shiro is the core of the filter, so if you are not logged in, it should direct requests to intercept, but not to the background process is logged in, before learning species, realm is written like this:
This is before the authentication method was considered to be the controller layer invokes the login method, then re-enter the realm species, to compare the account password, and then determine whether the authentication is successful, of course , this is the wrong understanding , new understanding of the following:
First, write a controller:
@Controller public class LoginController { @RequestMapping("/login") public String login() { return "login"; } @RequestMapping("/") public String home() { return "index"; } }
And you can see two paths, / login path to return to the login page / return to the Home (Why do you write, because shiro after the authentication, if the login, then sends the request to the root directory, followed by verification)
Then edit the realm login:
package com.zs.springboot.realm; import com.zs.springboot.model.User; import com.zs.springboot.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.session.Session; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.Map; public class LoginRealm extends AuthorizingRealm { @Autowired private UserService userService; /** * 授权方法 * @param principal * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { return null; } /** * 认证方法 * @param token * @return * @throws AuthenticationException * / @Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken token) throws AuthenticationException { // get the user name currently logged String username = (String) token.getPrincipal (); // the user to search the database of user information Map <String, Object> = Login userService.login (username); System.out.println (Login); // if the user does not exist exception is thrown IF ((Integer) login.get ( "code") == 404 ) { the throw new new UnknownAccountException ( "user does not exist" ); } //If the user exists, the user information acquiring the User User = (the User) login.get ( "User" ); // authentication SimpleAuthenticationInfo info = new new SimpleAuthenticationInfo (user.getUsername (), user.getPassword (), ByteSource.Util.bytes ( user.getSalt ()), the this .getName ()); // the user information into the session, the password aerial the session session = SecurityUtils.getSubject () the getSession ();. user.setPassword ( null ); session.setAttribute ( "User" , User); return info; } }
Then use Java classes springboot arranged shiro
package com.zs.springboot.config; import com.zs.springboot.realm.LoginRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; importorg.springframework.boot.SpringBootConfiguration; Import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; Import org.springframework.context.annotation.Bean; Import java.util.LinkedHashMap; Import a java.util.Map; / ** * Create shiro configuration class * / @SpringBootConfiguration public class ShiroConfig { / ** * the shiro lifecycle management to spring containers, equivalent to: * <the bean ID = "lifecycleBeanPostProcessor" class = "org.apache.shiro.spring.LifecycleBeanPostProcessor "/> * @return * / @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 密码加密 * @return */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); hashedCredentialsMatcher.setHashIterations(1024); hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true); return hashedCredentialsMatcher; } / ** * Cache Manager configuration shiro * @return * / @Bean public EhCacheManager ehCacheManager () { EhCacheManager ehCacheManager = new new EhCacheManager (); return ehCacheManager; } / ** * own configuration The realm * @return * / @Bean public LoginRealm loginRealm () { LoginRealm loginRealm = new new LoginRealm (); loginRealm.setCredentialsMatcher (hashedCredentialsMatcher ()); / *During the development phase does not need to buffer * / // loginRealm.setCacheManager (ehCacheManager ()); return loginRealm; } / ** * Create a security manager shiro * @return * / @Bean (name = "securityManager" ) public DefaultWebSecurityManager defaultWebSecurityManager () { defaultWebSecurityManager defaultWebSecurityManager = new new defaultWebSecurityManager (); defaultWebSecurityManager.setCacheManager (ehCacheManager ()); defaultWebSecurityManager.setRealm (loginRealm ()); return defaultWebSecurityManager; } / ** * Core: shiro default filter configuration of * / @Bean (name = "shiroFilter" ) public ShiroFilterFactoryBean shiroFilterFactoryBean () { ShiroFilterFactoryBean filter = new new ShiroFilterFactoryBean (); filter.setSecurityManager (defaultWebSecurityManager ()); filter.setLoginUrl ( "/ Login " ); // filter.setSuccessUrl (" / index "); filter.setUnauthorizedUrl (" / 404 " ); the Map <String, String> = filterChainDefinitionMap new new a LinkedHashMap <> (); filterChainDefinitionMap.put ( " / Zimbabwe Logout ", "logout"); / ** * * ** and the difference of * if there is a packet: com.zs.service has a service interface at the * packet, and a package for the bag another: impl, then the path of this package is com .zs.service.impl * If this is scan packages: com.zs.service / * then it only indicates that the interface in the current directory service, impl class in the package does not include * If the scan: com.zs.service / ** means that all things under the scanning service interfaces, including classes in impl bag * *: only that subdirectory of the current directory (a) * **: indicates that all directories under the current directory * / filterChainDefinitionMap.put ( "/ static / ** "," anon " ); filterChainDefinitionMap.put ( " / ** "," authc " ); filter.setFilterChainDefinitionMap (filterChainDefinitionMap); return filter; } / ** * @ConditionalOnMissingBean: Conditions Notes * When one can not find the bean will be loaded * springboot have the source code of the bean DefaultAdvisorAutoProxyCreator configuration, * then if myself, and configure the boot loader configuration will load into two Like the bean, it will conflict error! * After adding annotations condition, comes only when springboot can not be loaded into the bean, bean will load their own configuration information * @return * / @Bean @ConditionalOnMissingBean public The DefaultAdvisorAutoProxyCreator The DefaultAdvisorAutoProxyCreator () { The DefaultAdvisorAutoProxyCreator defaltAdverisor = new new The DefaultAdvisorAutoProxyCreator (); / * create a dynamic proxy object shiro by proxy, true representatives are cglib proxy * / defaltAdverisor.setProxyTargetClass ( to true ); return defaltAdverisor; } /** * AuthorizationAttributeSourceAdvisor * 授权源适配器,源数据 * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(defaultWebSecurityManager()); return advisor; } }
log in page:
<form action="login" method="post"> <input type="text" name="username"/> <input type="password" name="password"/> <input type="submit"/> </form>
Run import category, logon test (password database should be encrypted string)
shiro operating principle:
We first open the browser, sending login request, then shiro intercepts the request to see whether the request with a parameter, if no arguments, stated that this is the first time you log in, you need to jump to the login page and then return to the login page ,
After the landing page, enter account number and password, click Login, sending login request again, shrio again intercepted, check the parameters (username and password), indicates that the user wants to log in, then shiro detects whether the user has been authenticated, if already certified, direct release, if not authenticated, the process proceeds loginRealm perform authentication, then the authentication process to check whether the user through a user name, if there is information of the user is acquired, and then the user information into simpleAuthencationInfo object, the front end determines shiro database accessible to the user information and the user information transmitted is matched with a map to help understand: