`
rainingcn
  • 浏览: 25580 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

shiro spring 整合

 
阅读更多

用shiro来作为系统的权限控制,它和spring的整合比较简单。思路是:

    1. 首先用sping+struts2 做个最简单的登录

    2. 引入shiro

一:简单的登录

     1.login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<html>
<title>
    Login Page
</title>
<head>
    <title>Login Page</title>
</head>
<body>
<s:form action="login" method="post">
    <s:textfield name="user.id" label="UserId"/>
    <s:password name="user.password" label="Password"/>
    <s:submit value="Login"/>
</s:form>
</body>
</html>

     2. home.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<html>
<head>
    <title>Login Page</title>
</head>
<body>
Hello, <s:property value="user.id" />
</body>
</html>

  3.web.xml

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

 <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 4.struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="default" extends="struts-default" namespace="/">
        <action name="login" class="com.***.web.LoginAction">
            <result name="success">/home.jsp</result>
            <result name="input">/index.jsp</result>
        </action>
        <!-- Add your actions here -->
    </package>
</struts>

 5.LoginAction  把后面的带上来了,shiro判断这块可以去掉

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.rain.bo.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoginAction extends ActionSupport implements ModelDriven {
    /*--------------------------------------------
    |             C O N S T A N T S             |
    ============================================*/
    private static final transient Logger log = LoggerFactory.getLogger(LoginAction.class);
    /*--------------------------------------------
    |    I N S T A N C E   V A R I A B L E S    |
    ============================================*/

    private User user;
    /*--------------------------------------------
    |         C O N S T R U C T O R S           |
    ============================================*/

    /*--------------------------------------------
    |  A C C E S S O R S / M O D I F I E R S    |
    ============================================*/
    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }

    /*--------------------------------------------
    |               M E T H O D S               |
    ============================================*/
    @Override
    public String execute() throws Exception {
        Subject currentUser = SecurityUtils.getSubject();
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken(user.getId(), user.getPassword());
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
                return INPUT;
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                return INPUT;
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
                return INPUT;
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
               //...
            }
        }

        return SUCCESS;
    }

    @Override
    public Object getModel() {
        return user;
    }
}

  6. User.java

public class User {
   
    private String id;
    private String password;
   
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
   
}

 

以上能正常的登录

 

二。引入shiro

    1. web.xml 增加

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext-shiro.xml</param-value>
    </context-param>    
<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.applicationContext-shiro.xml

<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <description>Shiro 配置</description>
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login.jsp" />
        <property name="successUrl" value="/index.jsp" />
        <property name="unauthorizedUrl" value="/login.do" />
        <property name="filterChainDefinitions">
            <value>
                /login.jsp = anon
                /login* = anon
                /** = authc
            </value>
        </property>
    </bean>

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--设置自定义realm-->
        <!--<property name="realm" ref="monitorRealm" />-->
        <property name="realm" ref="iniRealm" />
    </bean>

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

    <!-- 使用配置文件管理 -->
    <bean id="iniRealm" class="org.apache.shiro.realm.text.IniRealm">
        <property name="resourcePath" value="classpath:/shiro.ini" />
    </bean>

    <!--自定义Realm 继承自AuthorizingRealm-->
    <bean id="monitorRealm" class="com.**.realm.MonitorRealm"></bean>
    <!-- securityManager -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod"
                  value="org.apache.shiro.SecurityUtils.setSecurityManager" />
        <property name="arguments" ref="securityManager" />
    </bean>

    <!-- Enable Shiro Annotations for Spring-configured beans.  Only run after -->
    <!-- the lifecycleBeanProcessor has run: -->
    <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>
</beans>

        MonitorRealm:自定义Realm,这里可以选择数据源是DB的、CAS的或者其它

        iniRealm : 使用ini配置文件来管理shiro的,demo时候或者系统不变的时候可以选择

3. MonitorRealm

import com.rain.bo.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.stereotype.Service;


@Service("monitorRealm")
public class MonitorRealm extends AuthorizingRealm {

   /* @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;
    @Autowired
    LoginLogService loginLogService;*/

    public MonitorRealm() {
        super();

    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        /*这里编写授权代码*/
        return  null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
        /*这里编写认证代码*/
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String userName = token.getUsername();
        if( userName != null && !"".equals(userName) ){
//            User user = accountManager.login(token.getUsername(),
//                    String.valueOf(token.getPassword()));
            if(token.getUsername().equals("admin") && String.valueOf(token.getPassword()).equals("123"))
                return new SimpleAuthenticationInfo(token.getUsername(), token.getPassword(), getName());
          /*  if( user != null )
                return new SimpleAuthenticationInfo(
                        user.getId(),user.getPassword(), getName());*/
        }
        return null;
    }

    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

}

 

三:

     可见引入shiro对原有系统的影响是超级轻微的,只是把原来对象(权限)的获得抛给了shiro来处理,至于获取对象之前和对象之后的流程操作基本上不用变

分享到:
评论
1 楼 bluewater112 2014-06-30  
按照你的配置,在action上增加@RequiresPermissions()注解时,会报错,提示找不到配置的action

相关推荐

Global site tag (gtag.js) - Google Analytics