SpringMVC+Hibernate+Shiro:
there is 5 steps to integrate the Shiro framework into the SpringMVC.
1. add the jar package:
<!-- Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.3</version>
</dependency>
<!-- Logging: this need for Hibernate-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<!-- this is need for the log -->
<groupId>jboss</groupId>
<artifactId>javassist</artifactId>
<version>3.3.ga</version>
</dependency>
2. the web.xml
<!-- the shiro filter
-->
<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>
3.
add the Shiro configureation in ApplicationContext.mxl
<!-- -============================================================================
the Shiro config
================================================================================= -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.w"/>
<property name="successUrl" value="/user/manageUsers.w"/>
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<!-- The 'filters' property is usually not necessary unless performing an override, which we
want to do here (make authc point to a PassthruAuthenticationFi
lter instead of the
default FormAuthenticationFilter
: -->
<property name="filterChainDefinitions">
<value>
/common/* = anon
/styles/* = anon
/img/* = anon
/user/* = authc, roles[admin]
/role/* = authc, perms[role:*]
/** = authc
</value>
</property>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManage
r">
<!-- Single realm app (realm configured next, below).
If you have multiple realms, use the 'realms'
property instead. -->
<property name="realm" ref="wushiRealm"/>
<!-- Uncomment this next property if you want heterogenous session access or clusterable/distributable
sessions.
The default value is 'http' which uses the Servlet container's HttpSession as the underlying
Session implementation.
<property name="sessionMode" value="native"/> -->
</bean>
<!-- Post processor that automatically invokes init() and destroy() methods -->
<bean id="lifecycleBeanPostProcess
or" class="org.apache.shiro.spring.LifecycleBeanPostProcess
or"/>
<!-- Spring AOP auto-proxy creation (required to support Shiro annotations) -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyC
reator"
depends-on="lifecycleBeanPostProcess
or" />
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSo
urceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
4. implement the Reaml class:
@Component
public class WushiRealm extends AuthorizingRealm {
static Logger logger = Logger.getLogger(WushiRealm.class.getName());
@Autowired
private UserDao userDao;
public WushiRealm() {
setName("WushiRealm"); //This name must match the name in the User class's getPrincipals() method
setCredentialsMatcher(new Sha256CredentialsMatcher
());
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Long userId = (Long) principals.fromRealm(getName()).iterator().next();
User user = this.userDao.getUser(userId);
logger.info("######the userId:="+ userId+" the pass:="+user.getPassword());
if( user != null ) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for( Role role : user.getRoles() ) {
info.addRole(role.getName());
info.addStringPermissions( role.getPermissions() );
}
return info;
} else {
return null;
}
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)token;
logger.info("######the username:="+usernamePasswordToken.getUsername()+" the pass:="+
usernamePasswordToken.getPassword());
User user=this.userDao.findUser(usernamePasswordToken.getUsername());
AuthenticationInfo authInfo=null;
if(user!=null){
authInfo=new SimpleAuthenticationInfo
(user.getId(),user.getPassword(), getName());
}
return authInfo;
}
}
5. develop the Controller for the login and logout:
@RequestMapping(value="/login", method=RequestMethod.GET)
public String showLoginForm(Model model, @ModelAttribute LoginCommand loginCommand){
return "/common/login";
}
@RequestMapping(value="/login", method=RequestMethod.POST)
public String login(Model model,HttpServletRequest request, @ModelAttribute("loginCommand") LoginCommand loginCommand, BindingResult errors){
logger.info("user:="+loginCommand.getUsername()+" password:="+loginCommand.getPassword());
UsernamePasswordToken token=new UsernamePasswordToken(loginCommand.getUsername(), loginCommand.getPassword(), loginCommand.isRememberMe());
try{
SecurityUtils.getSubject().login(token);
}catch(AuthenticationException e){
e.printStackTrace();
errors.reject( "error.login.generic", "Invalid username or password.
Please try again." );
}
if(errors.hasErrors()){
return showLoginForm(model,loginCommand);
}else{
request.getSession().setAttribute("currentUser", this.userService.getCurrentUser());
return "redirect:/home.w";
}
}
@RequestMapping("/logout")
public String logout(){
SecurityUtils.getSubject().logout();
return "redirect:/login.w";
}
there is 5 steps to integrate the Shiro framework into the SpringMVC.
1. add the jar package:
2. the web.xml
<!-- the shiro filter
4. implement the Reaml class:
public class WushiRealm extends AuthorizingRealm {
}
5. develop the Controller for the login and logout: