SpringMVC integrates Shiro with filterChainDefinitions filter configuration

SpringMVC integrates Shiro, a powerful and easy-to-use Java security framework that provides authentication, authorization, encryption, and session management functions.

 

Step 1: Configure web.xml

 

<!-- Configure the Shiro filter, first let Shiro filter the requests received by the system-->  

<!-- Here filter-name must correspond to <bean id="shiroFilter"/> defined in applicationContext.xml -->  

<!-- Use [/*] to match all requests to ensure that all controllable requests are filtered by Shiro -->  

<!-- This filter-mapping is usually placed first (i.e. before other filter-mappings) to ensure it is the first in the filter chain to work -->  

<filter>  

    <filter-name>shiroFilter</filter-name>  

    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  

    <init-param>  

    <!-- The default value of this value is false, which means that the life cycle is managed by SpringApplicationContext. If set to true, it means that it is managed by ServletContainer -->  

    <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>

 

 

Step 2: Configure applicationContext.xml

 

<!-- A custom Realm that inherits from AuthorizingRealm, that is, the class that specifies Shiro to authenticate user login is a custom ShiroDbRealm.java -->  

<bean id="myRealm" class="com.jadyer.realm.MyRealm"/>  

 

<!-- Shiro will use the Session of the servlet container by default, you can specify the use of Shiro's native Session through the sessionMode attribute -->  

<!-- That is, <property name="sessionMode" value="native"/>, see the official documentation for details -->  

<!-- This is mainly to set a custom single Realm application, if there are multiple Realms, you can use the 'realms' attribute instead -->  

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  

    <property name="realm" ref="myRealm"/>  

</bean>  

 

<!-- The Shiro main filter itself is very powerful, its power is that it supports the execution of any custom filter based on URL path expressions-->  

<!-- In web applications, Shiro's controllable web requests must be intercepted by Shiro's main filter. Shiro provides perfect support for Spring-based web applications -->  

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  

    <!-- Shiro's core security interface, this attribute is required -->  

    <property name="securityManager" ref="securityManager"/>  

    <!-- The link required to log in (can be replaced according to the URL of the project), non-essential attributes, the "/login.jsp" page in the root directory of the Web project will be automatically searched by default -->  

    <property name="loginUrl" value="/"/>  

    <!-- The connection to jump to after successful login (this property is not used in this example, because the processing logic after successful login is hard-coded as main.jsp in LoginController) -->  

    <!-- <property name="successUrl" value="/system/main"/> -->  

    <!-- The connection displayed when the user accesses a resource that is not authorized for him -->  

    <!-- If you want to test this property more clearly, you can modify its value, such as unauthorized.jsp, then log in with [Xuanyu] and visit /admin/listUser.jsp, you will see that the browser will display unauthorized.jsp -->  

    <property name="unauthorizedUrl" value="/"/>  

    <!-- Shiro connection constraint configuration, that is, the definition of the filter chain -->  

    <!-- Here you can cooperate with my article to understand the role of each filter connection http://blog.csdn.net/jadyer/article/details/12172839 -->  

    <!-- The path represented by the first '/' in the value below is relative to the value of HttpServletRequest.getContextPath() -->  

    <!-- anon: its corresponding filter is empty and does nothing, here * after .do and .jsp represents parameters, such as login.jsp?main -->  

    <!-- authc: The page under this filter can only be accessed after authentication, it is an interceptor built in Shiro org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  

    <property name="filterChainDefinitions">  

        <value>  

             /mydemo/login=anon  

             /mydemo/getVerifyCodeImage=anon  

             /main**=authc  

             /user/info**=authc  

             /admin/listUser**=authc,perms[admin:manage]  

        </value>  

    </property>

</bean>  

 

<!-- Guaranteed to implement the bean execution of Shiro's internal lifecycle function -->  

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  

 

<!-- To enable Shiro's annotations (such as @RequiresRoles, @RequiresPermissions), you need to use SpringAOP to scan classes annotated with Shiro, and perform security logic verification if necessary -->  

<!-- Configure the following two beans to achieve this function-->  

<!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run -->  

<!-- Since Shiro annotations are not used in this example, these two beans are commented out (personally, I think that the permissions are hard-coded in the program through annotations, which is not very convenient to view, so there is no need to use them) -->  

<!--   

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>  

  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  

    <property name="securityManager" ref="securityManager"/>  

  </bean>  

-->

 

Step 3: Custom Realm Class

 

public class MyRealm extends AuthorizingRealm {  

    /** 

     * Grant roles and permissions to the currently logged in Subject 

     * @see Tested: In this example, the time to call this method is when the authorized resource is accessed 

     * @see Tested: and the logic in this method is executed every time the resource that requires authorization is accessed, which indicates that the AuthorizationCache is not enabled by default in this example 

     * @see Personally, if you use the ConcurrentMapCache support provided by Spring 3.1, you can flexibly decide whether to enable AuthorizationCache 

     * @see For example, when obtaining permission information from the database, first access the cache provided by Spring 3.1 instead of using the AuthorizationCache provided by Shior 

     */  

    @Override  

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){  

        //Get the currently logged in username, equivalent to (String)principals.fromRealm(this.getName()).iterator().next()  

        String currentUsername = (String)super.getAvailablePrincipal(principals);  

//      List<String> roleList = new ArrayList<String>();  

//      List<String> permissionList = new ArrayList<String>();  

// //Get the details of the currently logged in user from the database  

//      User user = userService.getByUsername(currentUsername);  

//      if(null != user){  

// //The entity class User contains entity class information of user roles  

// if (null! = user.getRoles () && user.getRoles (). size ()> 0) {  

// //Get the role of the currently logged in user  

//              for(Role role : user.getRoles()){  

//                  roleList.add(role.getName());  

// //The entity class Role contains entity class information with role permissions  

//                  if(null!=role.getPermissions() && role.getPermissions().size()>0){  

// //Get permission  

//                      for(Permission pmss : role.getPermissions()){  

//                          if(!StringUtils.isEmpty(pmss.getPermission())){  

//                              permissionList.add(pmss.getPermission());  

//                          }  

//                      }  

//                  }  

//              }  

//          }  

//      }else{  

//          throw new AuthorizationException();  

//      }  

// //Set roles and permissions for the current user  

//      SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();  

//      simpleAuthorInfo.addRoles(roleList);  

//      simpleAuthorInfo.addStringPermissions(permissionList);  

        SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();  

        //Actually it may be fetched from the database as noted above  

        if(null!=currentUsername && "mike".equals(currentUsername)){  

            //Add a role, not in the sense of configuration, but to prove that the user has the admin role    

            simpleAuthorInfo.addRole("admin");  

            //add permission  

            simpleAuthorInfo.addStringPermission("admin:manage");  

            System.out.println("User [mike] has been given [admin] role and [admin:manage] permission");  

            return simpleAuthorInfo;  

        }

        //If the method does nothing and returns null directly, it will cause any user to automatically jump to the address specified by unauthorizedUrl when accessing /admin/listUser.jsp  

        //See the configuration of <bean id="shiroFilter"> in applicationContext.xml  

        return null;  

    }  

 

 

    /** 

     * Verify the currently logged in Subject 

     * @see Tested: In this example, the call timing of this method is when Subject.login() is executed in the LoginController.login() method 

     */  

    @Override  

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {  

        // Get a token based on username and password  

        //Actually this authcToken is passed from currentUser.login(token) in LoginController  

        // Both token references are the same

        UsernamePasswordToken token = (UsernamePasswordToken)authcToken;  

        System.out.println("The token obtained when verifying the current Subject is " + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));  

//      User user = userService.getByUsername(token.getUsername());  

//      if(null != user){  

//          AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), user.getNickname());  

//          this.setSession("currentUser", user);  

//          return authcInfo;  

//      }else{  

//          return null;  

//      }  

        //There is no need to compare here, the logic of the comparison will be done by Shiro, we only need to return a correct verification information related to the token  

        //To put it bluntly, the first parameter fills in the login user name, and the second parameter fills in the legal login password (it can be obtained from the database, in this example, it is hard-coded for demonstration)  

        //In this way, only the user and password specified here can be authenticated on subsequent login pages  

        if("mike".equals(token.getUsername())){  

            AuthenticationInfo authcInfo = new SimpleAuthenticationInfo("mike", "mike", this.getName());  

            this.setSession("currentUser", "mike");  

            return authcInfo;  

        }

        //When the SimpleAuthenticationInfo object corresponding to the login user name is not returned, an UnknownAccountException will be thrown in the LoginController  

        return null;  

    }  

 

 

    /** 

     * Put some data into ShiroSession for use elsewhere 

     * @see For example Controller, you can get it directly with HttpSession.getAttribute(key) when using it 

     */  

    private void setSession(Object key, Object value){  

        Subject currentUser = SecurityUtils.getSubject();  

        if(null != currentUser){  

            Session session = currentUser.getSession();  

            System.out.println("Session default timeout is [" + session.getTimeout() + "]ms");  

            if(null != session){  

                session.setAttribute(key, value);  

            }  

        }  

    }  

}

 

Shiro permission management filterChainDefinitions filter configuration 

Foreword: Shiro's three core modules: Subject (user), SecurityManager (framework heart), Realm ("bridge" between Shiro and application security data) 

SecurityManager manages cacheManager cache and sessionManager session, sessionManager manages sessionDAO session DAO and sessionIdCookie session ID generator and sessionValidationScheduler session validation scheduler, cacheManager is implemented by using Ehcache, and Realm is implemented by its own custom or other means of permission storage, such as login etc. 

Using the unified data access layer, by writing entity classes, writing Repository interfaces, and finally implementing through configuration files 

Repository is the identity, spring automatically scans, CrudRepository inherits Repository to implement curd, PagingAndSortingRepository inherits CrudRepository to implement paging sorting, JpaRepository inherits PagingAndSortingRepository to implement JPA specification related methods, JpaSpecificationExecutor does not belong to Repository, it is special, it implements a set of JPA Criteria query related methods

 

/** 

* Shiro-1.2.2 built-in FilterChain 

* @see ========================================================================================================= 

* @see 1) When Shiro verifies the URL, if the URL matches successfully, it will not continue to match and search (so pay attention to the URL order in the configuration file, especially when using wildcards) 

* @see Therefore, the configuration order of filterChainDefinitions is from top to bottom, whichever is the top 

* @see 2) When running a web application, Shiro will create some useful default Filter instances and automatically make them available in the [main] item 

* @see The default Filter instance that is automatically available is defined by the DefaultFilter enumeration class, and the name field of the enumeration is the name that can be configured 

* @see anon—————org.apache.shiro.web.filter.authc.AnonymousFilter 

* @see authc————–org.apache.shiro.web.filter.authc.FormAuthenticationFilter 

* @see authcBasic———org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter 

* @see logout————-org.apache.shiro.web.filter.authc.LogoutFilter 

* @see noSessionCreation–org.apache.shiro.web.filter.session.NoSessionCreationFilter 

* @see perms————–org.apache.shiro.web.filter.authz.PermissionAuthorizationFilter 

* portsee port ————— org.apache.shiro.web.filter.authz.PortFilter 

* @see rest—————org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter 

* @see roles————–org.apache.shiro.web.filter.authz.RolesAuthorizationFilter 

* @see ssl—————-org.apache.shiro.web.filter.authz.SslFilter 

*@see user—————org.apache.shiro.web.filter.authz.UserFilter 

* @see ========================================================================================================= 

* @see 3) These filters can generally be divided into two groups 

* @see anon,authc,authcBasic,user is the first set of authentication filters 

* @see perms,port,rest,roles,ssl are the second set of authorization filters 

* @see Note that user and authc are different: when rememberMe is enabled in the app, the user can be a user next time they visit, but it will never be authc, because authc needs to be re-authenticated 

* @see user means that the user is not necessarily authenticated, as long as the user who has been remembered by Shiro's login status can initiate a request normally, such as rememberMe 

* @see To put it bluntly, a previous user turned on rememberMe when he logged in, and then he closed the browser. The next time he visits, he will be a user without authc 

* @see ========================================================================================================== 

* @see 4) to give some examples 

* @see /admin=authc,roles[admin] means that the user must be authenticated and have the admin role to initiate a '/admin' request normally 

* @see /edit=authc,perms[admin:edit] Indicates that the user must be authenticated and have admin:edit privileges to initiate the '/edit' request normally 

* @see /home=user means that the user does not necessarily need to have been authenticated, as long as the login status has been remembered by Shiro, the '/home' request can be initiated normally 

* @see ========================================================================================================== 

* @see 5) The default filters are commonly used as follows (note that two stars are used in the URL Pattern, so as to achieve full matching at any level) 

* @see /admins/**=anon No parameter, it can be used anonymously, which can be understood as an anonymous user or tourist 

* @see /admins/user/**=authc No parameter, it means authentication is required to use 

* @see /admins/user/**=authcBasic No parameter, means httpBasic authentication 

* @see /admins/user/**=user No parameter, indicating that there must be a user, no check is performed when logging in 

* @see /admins/user/**=ssl No parameter, indicating a secure URL request, the protocol is https 

* @see /admins/user/*=perms[user:add:] 

* @see parameters can be written multiple times, quotation marks must be added for multiple parameters, and the parameters are separated by commas, such as /admins/user/*=perms[“user:add:,user:modify:*”] 

* @see When there are multiple parameters, each parameter must be passed to pass, which is equivalent to the isPermitedAll() method 

* @see /admins/user/**=port[8081] 

* @see When the requested URL port is not 8081, jump to schema://serverName:8081?queryString 

* @see where schmal is the protocol http or https, etc., serverName is the Host you are visiting, 8081 is the Port port, and queryString is the parameter in the URL you are visiting? 

* @see /admins/user/**=rest[user] 

* @see According to the requested method, it is equivalent to /admins/user/**=perms[user:method], where method is post, get, delete, etc. 

* @see /admins/user/**=roles[admin] 

* @see parameters can be written multiple times, quotes must be added when multiple, and the parameters are separated by commas, such as /admins/user/**=roles[“admin,guest”] 

* @see When there are multiple parameters, each parameter must be passed to pass, which is equivalent to the hasAllRoles() method 

* @see

 

 

Shiro logout configuration method in spring 

There are two ways to implement logout 

1. Implement your own logout method in an ordinary action, get the Subject, and logout 

This needs to configure filterChainDefinitions in ShiroFilterFactoryBean 

The url of the corresponding action is a 

 

# some example chain definitions: 

/index.htm = anon 

/logout = anon 

/unauthed = anon 

/console/** = anon 

/css/** = anon 

/js/** = anon 

/lib/** = anon 

/admin/** = authc, roles[admin] 

/docs/** = authc, perms[document:read] 

/** = authc 

# more URL-to-FilterChain definitions here 

Use the logout filter provided by shiro 

Need to define the corresponding bean 

 

 

Then configure the corresponding url filter to logout as follows

 

<property name="filterChainDefinitions">

            <value>

                # some example chain definitions:

                /index.htm = anon

                /logout = logout

                /unauthed = anon

                /console/** = anon

                /css/** = anon

                /js/** = anon

                /lib/** = anon

                /admin/** = authc, roles[admin]

                /docs/** = authc, perms[document:read]

                /** = authc

                # more URL-to-FilterChain definitions here

            </value>

 

Note: anon, authcBasic, auchc, user are authentication filters, perms, roles, ssl, rest, port are authorization filters

 

Detailed explanation of the final configuration of various parameters 

anon: For example, /admins/**=anon has no parameters, which means it can be used anonymously. 

authc: For example, /admins/user/**=authc means authentication (login) is required to use, no parameters 

roles: example /admins/user/=roles[admin], multiple parameters can be written, quotes must be added when multiple, and the parameters are separated by commas, when there are multiple parameters, such as admins/user/=roles ["admin,guest"], each parameter is passed only when passed, which is equivalent to the hasAllRoles() method. 

perms: example /admins/user/=perms[user:add:], multiple parameters can be written, quotes must be added when multiple, and the parameters are separated by commas, for example /admins/user/=perms[“user :add:,user:modify:*”], when there are multiple parameters, each parameter must be passed before passing, which is equivalent to the isPermitedAll() method. 

rest: example /admins/user/=rest[user], according to the requested method, equivalent to /admins/user/=perms[user:method], where the method is post, get, delete, etc. 

port: example /admins/user/**=port[8081], when the port of the requested url is not 8081, it will jump to schema://serverName:8081?queryString, where schmal is the protocol http or https, etc., serverName is you The accessed host, 8081 is the port of the port in the url configuration, queryString 

Is it in the url you visited? the following parameters. 

authcBasic: For example /admins/user/**=authcBasic no parameter means httpBasic authentication 

ssl: example /admins/user/**=ssl has no parameters, indicating a secure url request, the protocol is https 

user: For example, /admins/user/**=user has no parameter to indicate that a user must exist, and no check is performed when logging in 

Note: anon, authcBasic, auchc, user are authentication filters, 

perms, roles, ssl, rest, port are authorization filters

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326251030&siteId=291194637