This article is based on your ability to build Springmvc+mybatis+maven projects, and on this basis, join the Shiro framework. A demo will be provided at the end of the article. principle:
Most frameworks conform to this logic: there is a core controller that the user calls the core controller, and then the core controller finds the corresponding response event to process, and then feedback the results to the user. And this core controller, we do not need to understand in-depth, as long as the correct configuration can be.
For Shiro, he is handling the user's permissions and authentication, so we are slightly flexible: the user (Subject) calls the Shiro Core controller (Shiro securitymanage), and then the core controller for the corresponding processing (to obtain the user's authentication results or permissions), Then feedback to the user. As shown in the following illustration:
For developers, just:
1) Configure Shiro SecurityManager
2) define your realm. Because the user/permissions vary by project, the Shiro framework requires the user to customize the user/permission and then inject it through realm.
3) Access Shiro SecurityManager via subject
Code implementation:
First step: Introduce the required jar in the Pom.xml file
<span style= "White-space:pre" > </span><dependency> <groupid>org.apache.shiro</groupid > <artifactId>shiro-core</artifactId> <version>1.2.4</version> </dependency> &l T;dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> & lt;version>1.2.4</version> </dependency> <dependency> <groupid>org.apache.shiro</ groupid> <artifactId>shiro-spring</artifactId> <version>1.2.4</version> </dependenc y> <span style= "White-space:pre" > </span><dependency> <span style= "White-space:pre" > < /span><groupid>com.alibaba</groupid> <span style= "White-space:pre" > </span>< artifactid>druid</artifactid> <span style= "White-space:pre" > </span><version>1.0.11 </version> <span style= "White-space:pre" > </spAn></dependency>
The second step: Define the Shiro configuration file applicationcontext-shiro.xml; We only do three things, configure the SecurityManager, then inject the custom realm, and finally filter the specified URL (the red callout is the one that needs to be modified by itself. )。
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns= "Http://www.springframework.org/schema/beans" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:tx= "Http://www.springframework.org/schema/tx" xmlns:aop= " Http://www.springframework.org/schema/aop "xmlns:context=" Http://www.springframework.org/schema/context "xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans-4.2.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/ Spring-tx-4.2.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ Spring-aop-4.2.xsd Http://www.springframework.org/schema/context http://www.springframework.org/schema/context/
Spring-context-4.2.xsd "> <!--inherit from Authorizingrealm custom realm, which specifies Shiro to verify that the user is logged on as a custom Shirodbrealm.java- <bean id= "Myrealm" <span style= "color: #3333ff;" >class= "<span style=" color: #ff0000; " >com.reaLm. Myrealm "</span>/> <!--here is mainly to set up a custom single realm app, 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> <!--Shiro Main filter itself is very powerful, its strength is that it supports any URL path expression-based, custom filter execution--<!--Web applications, Shir o controllable Web requests must be intercepted by the Shiro primary filter, Shiro provides the perfect support for spring-based Web applications-<bean id= "Shirofilter" class= " Org.apache.shiro.spring.web.ShiroFilterFactoryBean "> <!--Shiro's core security interface, this property is required--<property name=" SecurityManager "ref=" SecurityManager "/> <!--require a login link (can be replaced according to the URL of the project), non-required properties, by default automatically find"/login.jsp "under the Web project root directory Page-<property name= "loginurl" value= "<span style=" color: #cc0000; "
>/items/login</span> "<!--the connection to jump after successful login (this attribute is not used in this example, because the processing logic after the successful login is hardcoded in Logincontroller to main.jsp)-- <!--<property name= "Successurl" value= "/"/>-<!--when users access resources that are not authorized, the connections that are displayed-<!--if you want to test this property more clearly, you can Modify its value, such as Unauthor.jsp, and then use [Xuan Yu] login after access to/admin/listuser.jsp see the browser will show unauthor.jsp---<property name= "Unauthorizedurl" value= "/"/ > <!--Shiro connection constraint configuration, that is, the definition of the filter chain-<!--Here you can work with my article to understand the effects of each filter connection http://blog.csdn.net/jadyer/article/details/ 12172839-<!--the value below the first '/' represents the path that is relative to Httpservletrequest.getcontextpath () and <!-- Anon: It corresponds to the filter inside is empty, nothing to do, here. Do and. JSP after the * represents parameters, such as Login.jsp?main--<!--AUTHC: The filter under the page must be verified before access, It is a shiro built-in interceptor Org.apache.shiro.web.filter.authc.FormAuthenticationFilter-<property name= " Filterchaindefinitions "> <value> <span style=" color: #ff0000; " >/items/queryItems=authc</span> </value> </property> </bean> </beans>
Step three: Customize Realm
Package Com.realm;
Import Org.apache.commons.lang.builder.ReflectionToStringBuilder;
Import Org.apache.commons.lang.builder.ToStringStyle;
Import Org.apache.shiro.SecurityUtils;
Import org.apache.shiro.authc.AuthenticationException;
Import Org.apache.shiro.authc.AuthenticationInfo;
Import Org.apache.shiro.authc.AuthenticationToken;
Import Org.apache.shiro.authc.SimpleAuthenticationInfo;
Import Org.apache.shiro.authc.UsernamePasswordToken;
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.subject.Subject; public class Myrealm extends Authorizingrealm {/** * Grant roles and permissions for the currently logged on subject */@Override protected Authorizat
Ioninfo Dogetauthorizationinfo (principalcollection principals) {///here should go to the database to query the user rights information, and then return the permission information to null; /** * Verify the subject of the current login
*/@Override protected AuthenticationInfo dogetauthenticationinfo (Authenticationtoken authctoken) throws Authenti
cationexception {//Get tokens based on username and password Usernamepasswordtoken token = (usernamepasswordtoken) Authctoken; System.out.println ("Get to token when validating current subject" + reflectiontostringbuilder.tostring (token, Tostringstyle.multi_line_
STYLE)); The database should be queried for user information and then compared to the data coming from the page.
Here we return directly, without doing any processing.
System.out.println (Token.getusername () +token.getpassword ()); AuthenticationInfo authcinfo = new Simpleauthenticationinfo (Token.getusername (), Token.getpassword (), This.getName ()
);
This.setsession ("CurrentUser", Token.getusername ());
return authcinfo; /** * Put some data into the shirosession so that it can be used elsewhere */private void Setsession (object key, Object value) {Subject Curre
NtUser = Securityutils.getsubject ();
if (null! = CurrentUser) {Session session = Currentuser.getsession ();
Session.settimeout (10000); SYSTEM.OUT.PRINTLN ("Session default time-out is [" + session.gettimeout () +"] milliseconds");
if (null! = session) {Session.setattribute (key, value);
}
}
}
}
Fourth step: Access Shiro SecurityManager via subject, we only need to add in the interface:
Subject sub = Securityutils.getsubject ();
try {
Usernamepasswordtoken token = new Usernamepasswordtoken (Item.getid (), Item.getname ());
Token.setrememberme (true);
<span style= "White-space:pre" > </span>sub.login (token);
} catch ( Incorrectcredentialsexception e) {
return null;
}
if (sub.isauthenticated ()) {
System.out.println ("Verified by");
}
Of course, remember to refer to Applicationcontext-shiro.xml in Web. XML and configure the use of this filter
<!--loading Spring containers--<context-param> <param-name>contextConfigLocation</param-name> < param-value> classpath:config/spring/applicationcontext-*.xml <span style= "White-space:pre" > </span ></param-value> </context-param> <listener> <listener-class> Org.springframework.web.context.contextloaderlistener</listener-class> </listener> <!--configuration Shiro Filter
, first let the Shiro filter system receive the request-<!--here Filter-name must correspond to the <bean id= "shirofilter" defined in Applicationcontext.xml/> <!--use [/*] to match all requests to ensure that all controllable requests are Shiro filtered-<!--usually put this filter-mapping first (that is, the front of the other filter-mapping). To ensure it is the first function in the filter chain--<filter> <filter-name>shiroFilter</filter-name> <filter-class> Org.springframework.web.filter.delegatingfilterproxy</filter-class> <init-param> <!--This value defaults to False, Indicates that the life cycle is managed by Springapplicationcontext, and set to True means Servletcontainer managed by-<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>
Demo
The database used by demo is Oracle and requires only one table My_item, containing three fields: ID, name, price.
How to test:
Interface 1:http://localhost:8080/study/items/queryitems
Interface 2:http://localhost:8080/study/items/login
Access interface 1 will automatically jump to interface 2, and then enter interface 1 in the browser, it will show the query results of interface 1. In order to test, I set the session expiration time is 10s, the hand speed is not too slow, 10s after the Access interface 1 or will automatically jump to interface 2.
Special thanks to Zhang Kaitao Teacher's Shiro tutorial, of course, there are teachers who admire the hole.