There are too many introductions about Shiro online, so I won't go into details. The purpose of this article is to record the key points of using configuration.
1. for Web. xml configuration, Shiro's filter must be placed before other filters.
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <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>
2. Spring context configurations are all taken from the official website and will not be detailed. Pay attention to the following issues:
1) The realm provided by Shiro is not required, so I wrote
2) successurl and unauthorizedurl did not work during debugging. Later, the reason is unknown. It may be due to a problem in the code or configuration. For example, to test the permission annotation, in login action, a private method with @ requirespermissions ("account: Create") is called.
<!-- shiro security --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login"/> <property name="successUrl" value="/welcome"/> <property name="unauthorizedUrl" value="/refuse"/> <property name="filterChainDefinitions"> <value>/refuse = anon<!-- /welcome = perms[accout:edit] -->/** = authc </value> </property></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="customRealm"/></bean><bean id="customRealm" class="com.capgemini.framework.common.access.CustomShiraRealm" /><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
3. To support Shiro annotations, add two bean definitions in applicationcontext. XML as described in the official document: defaultadvisorautoproxycreator and authorizationattributesourceadvisor.
But the test does not work, search for a long time, finally find the reason, the original use of spring MVC words need to write the two bean definitions in the corresponding springmvc-servlet.xml file, and add simplemappingexceptionresolver
<!-- Support Shiro Annotation --><bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">shiro-test/refuse</prop> </props> </property> </bean> <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>
4. The custom realm must inherit authorizingrealm and implement two Abstract METHODS: dogetauthorizationinfo and dogetauthenticationinfo.
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.fromRealm(getName()).iterator().next();if (username != null) {try {User user = userMgntService.getUserByUserCode(username);if (user != null && user.getRole() != null) {SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.addRole(user.getRole().getRoleName());info.addStringPermission("account:view");return info;}} catch (AppException e) {logger.error(e, e);}}return null;}
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken ) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authcToken;String userName = token.getUsername();if (userName != null && !"".equals(userName.trim())) {try {User user = userMgntService.getUserByUserCode(token.getUsername());if (user != null && user.getPassword().equals(String.valueOf(token.getPassword())))return new SimpleAuthenticationInfo(user.getUserCode(), user.getPassword(), getName());} catch (AppException e) {logger.error(e, e);}}return null;}
5. If the JSP login form is written in the official document, and the form element names are the same as those in the document, login action does not need to perform many operations. You only need to complete the jump of the verification failure. If the verification succeeds, it will not return to/login. Instead, it will jump from realm to successurl. The defaultFormauthenticationfilter will find the three requestsParameters:Username,PasswordAndRememberme. If you have to use different names, set the parameters of formauthenticationfilter.
<form action="${pageContext.request.contextPath}/login" method="post"> Username: <input type="text" name="username"/> <br/> Password: <input type="password" name="password"/> ... <input type="checkbox" name="rememberMe" value="true"/>Remember Me? ...</form>
[main]...authc.loginUrl = /whatever.jspauthc.usernameParam = somethingOtherThanUsernameauthc.passwordParam = somethingOtherThanPasswordauthc.rememberMeParam = somethingOtherThanRememberMe...
@RequestMapping(value = "/login")public String login(String username, String password) { return "shiro-test/login";}