shiro的使用1 简单的认证

 

 
有空学了一个简单的安全框架shiro,资料比较少,在百度和google上能搜到的中文我看过了,剩下的时间有空会研究下官网的文章和查看下源码,
 

简单的分享一些学习过程;

1,简单的一些概念上的认知

2,使用认证的基本流程

3,shiro集成spring完成简单的认证流程,已实现

  •     <bean id="myRealm" class="com.util.MysqlJdbcRealM"/>
  • 1 建一个maven的web项目,引入依赖
      springmvc的的依赖
          <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>3.2.0.RELEASE</version>
            </dependency>
    shiro跟spring集成的插件
     <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.3</version>
            </dependency>
    2 配置web.xml
    指出spring容器的配置文件位置
    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:context_config.xml</param-value>
        </context-param>
    指出spring在web容器中的代号
        <context-param>
            <param-name>webAppRootKey</param-name>
            <param-value>wechatSystem</param-value>
        </context-param>
    初始化spring的容器
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    spring mvc的分发器
        <servlet>
              <servlet-name>admin</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:admin-dispatcher-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
         </servlet>
         <servlet-mapping>
              <servlet-name>admin</servlet-name>
              <url-pattern>/</url-pattern>
         </servlet-mapping>
    spring跟shiro集成的过滤代理
     <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>/admin/*</url-pattern>
        </filter-mapping>
        <!-- 字符过滤,保存中文的时候用到 -->
        <filter>
            <filter-name>characterEncoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    3 配置shiroFilter实例
     <!--shiro的配置,关键两点,配置SecurityManager和依赖的RealM-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/admin/login" />
            <property name="successUrl" value="/admin/home" />
            <property name="unauthorizedUrl" value="/admin/login" />
            <property name="filters">
                <map>
                    <entry key="anno" value-ref="anno"/>
                    <entry key="authc" value-ref="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitionMap">
                <map>
                    <entry key="anon" value="anon"/>
                    <entry key="authc" value="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /admin/login=anon
                    /admin/validCode=anon
                    /user/**=authc
                    /role/**=authc
                    /permission/**=authc
                    /**=authc
                </value>
            </property>
        </bean>
        <bean id="authc" class="com.util.filter.MyAccessFilter"/>
        <bean id="anno" class="org.apache.shiro.web.filter.authc.AnonymousFilter"/>
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="myRealm"/>
        </bean>

        <bean id="myRealm" class="com.util.MysqlJdbcRealM"/>



    4 开发跟shiro交互的RealM,一般把权限信息放到db中
    package com.util;

    import com.domain.User;
    import com.domain.UserDto;
    import com.google.common.base.Strings;
    import com.service.UserDtoService;
    import com.service.UserService;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.jdbc.JdbcRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * User: cutter.li
    * Date: 2014/6/19 0019
    * Time: 15:24
    * 备注: 自定义的mysql数据源
    */
    @Component
    public class MysqlJdbcRealM extends JdbcRealm {

        @Resource
        private UserService userService;

        //登录认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
            String username = String.valueOf(usernamePasswordToken.getUsername());
            User user = userService.findByUserName(username);
            AuthenticationInfo authenticationInfo = null;
            if (null != user) {
                String password = new String(usernamePasswordToken.getPassword());
                if (password.equals(user.getPassword())) {
                    authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
                }
            }
            return authenticationInfo;
        }

        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

            String username = (String) principals.getPrimaryPrincipal();
            if (!Strings.isNullOrEmpty(username)) {
                SimpleAuthorizationInfo authenticationInfo = new SimpleAuthorizationInfo();
                authenticationInfo.setRoles(userService.findRolesStr(username));
                authenticationInfo.setStringPermissions(userService.findPermissionsStr(username));
                return authenticationInfo;
            }
            return null;

        }
    }
     
    5 简单的登录页面,功能测试


    6 controller的实现:
     @RequestMapping(value = "login", method = RequestMethod.POST)
        public ResponseEntity<Message> loginSubmit(String username, String password, String vcode, HttpServletRequest request) {
            message.setSuccess();
            validateLogin(message, username, password, vcode);
            try {
    //            String code = request.getSession().getAttribute(AppConstant.KAPTCHA_SESSION_KEY).toString();
    //            if (!vcode.equalsIgnoreCase(code)) {
    //                message.setCode(AppConstant.VALIDCODE_ERROR);
    //                message.setMsg("验证码错误");
    //            }
                if (message.isSuccess()) {

                    Subject subject = SecurityUtils.getSubject();
                    subject.login(new UsernamePasswordToken(username, password));

                    if (subject.isAuthenticated()) {
                            message.setMsg("登录成功");
                    } else {
                        message.setCode(AppConstant.USERNAME_NOTEXIST);
                        message.setMsg("用户名/密码错误");
                    }
                }
            }catch (AuthenticationException ex){
                message.setCode(AppConstant.USERNAME_NOTEXIST);
                message.setMsg("用户名/密码错误");
                ex.printStackTrace();
            }
            finally {
                return new ResponseEntity<Message>(message, HttpStatus.OK);
            }

        }
     
    7 指定认证的策略和多数据源
        <!--shiro的配置-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/admin/login" />
            <property name="successUrl" value="/admin/home" />
            <property name="unauthorizedUrl" value="/admin/login" />
            <property name="filters">
                <map>
                    <entry key="anno" value-ref="anno"/>
                    <entry key="authc" value-ref="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitionMap">
                <map>
                    <entry key="anon" value="anon"/>
                    <entry key="authc" value="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /admin/login=anon
                    /admin/validCode=anon
                    /user/**=authc
                    /role/**=authc
                    /permission/**=authc
                    /**=authc
                </value>
            </property>
        </bean>
        <bean id="authc" class="com.util.filter.MyAccessFilter"/>
        <bean id="anno" class="org.apache.shiro.web.filter.authc.AnonymousFilter"/>
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="authenticator" ref="modelAuthricator"/>
        </bean>
        <bean id="modelAuthricator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <property name="authenticationStrategy" ref="firstSuccess"/>
            <property name="realms">
               <list>
                 <ref local="myRealm"/>
               </list>
            </property>
        </bean>
        <bean id="firstSuccess" class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/>

    简单的分享一些学习过程;

    1,简单的一些概念上的认知

    2,使用认证的基本流程

    3,shiro集成spring完成简单的认证流程,已实现

  •     <bean id="myRealm" class="com.util.MysqlJdbcRealM"/>
  • 1 建一个maven的web项目,引入依赖
      springmvc的的依赖
          <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>3.2.0.RELEASE</version>
            </dependency>
    shiro跟spring集成的插件
     <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.2.3</version>
            </dependency>
    2 配置web.xml
    指出spring容器的配置文件位置
    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:context_config.xml</param-value>
        </context-param>
    指出spring在web容器中的代号
        <context-param>
            <param-name>webAppRootKey</param-name>
            <param-value>wechatSystem</param-value>
        </context-param>
    初始化spring的容器
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    spring mvc的分发器
        <servlet>
              <servlet-name>admin</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:admin-dispatcher-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
         </servlet>
         <servlet-mapping>
              <servlet-name>admin</servlet-name>
              <url-pattern>/</url-pattern>
         </servlet-mapping>
    spring跟shiro集成的过滤代理
     <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>/admin/*</url-pattern>
        </filter-mapping>
        <!-- 字符过滤,保存中文的时候用到 -->
        <filter>
            <filter-name>characterEncoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>characterEncoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    3 配置shiroFilter实例
     <!--shiro的配置,关键两点,配置SecurityManager和依赖的RealM-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/admin/login" />
            <property name="successUrl" value="/admin/home" />
            <property name="unauthorizedUrl" value="/admin/login" />
            <property name="filters">
                <map>
                    <entry key="anno" value-ref="anno"/>
                    <entry key="authc" value-ref="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitionMap">
                <map>
                    <entry key="anon" value="anon"/>
                    <entry key="authc" value="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /admin/login=anon
                    /admin/validCode=anon
                    /user/**=authc
                    /role/**=authc
                    /permission/**=authc
                    /**=authc
                </value>
            </property>
        </bean>
        <bean id="authc" class="com.util.filter.MyAccessFilter"/>
        <bean id="anno" class="org.apache.shiro.web.filter.authc.AnonymousFilter"/>
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="myRealm"/>
        </bean>

        <bean id="myRealm" class="com.util.MysqlJdbcRealM"/>



    4 开发跟shiro交互的RealM,一般把权限信息放到db中
    package com.util;

    import com.domain.User;
    import com.domain.UserDto;
    import com.google.common.base.Strings;
    import com.service.UserDtoService;
    import com.service.UserService;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.jdbc.JdbcRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;

    import javax.annotation.Resource;

    /**
    * User: cutter.li
    * Date: 2014/6/19 0019
    * Time: 15:24
    * 备注: 自定义的mysql数据源
    */
    @Component
    public class MysqlJdbcRealM extends JdbcRealm {

        @Resource
        private UserService userService;

        //登录认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
            String username = String.valueOf(usernamePasswordToken.getUsername());
            User user = userService.findByUserName(username);
            AuthenticationInfo authenticationInfo = null;
            if (null != user) {
                String password = new String(usernamePasswordToken.getPassword());
                if (password.equals(user.getPassword())) {
                    authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
                }
            }
            return authenticationInfo;
        }

        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

            String username = (String) principals.getPrimaryPrincipal();
            if (!Strings.isNullOrEmpty(username)) {
                SimpleAuthorizationInfo authenticationInfo = new SimpleAuthorizationInfo();
                authenticationInfo.setRoles(userService.findRolesStr(username));
                authenticationInfo.setStringPermissions(userService.findPermissionsStr(username));
                return authenticationInfo;
            }
            return null;

        }
    }
     
    5 简单的登录页面,功能测试


    6 controller的实现:
     @RequestMapping(value = "login", method = RequestMethod.POST)
        public ResponseEntity<Message> loginSubmit(String username, String password, String vcode, HttpServletRequest request) {
            message.setSuccess();
            validateLogin(message, username, password, vcode);
            try {
    //            String code = request.getSession().getAttribute(AppConstant.KAPTCHA_SESSION_KEY).toString();
    //            if (!vcode.equalsIgnoreCase(code)) {
    //                message.setCode(AppConstant.VALIDCODE_ERROR);
    //                message.setMsg("验证码错误");
    //            }
                if (message.isSuccess()) {

                    Subject subject = SecurityUtils.getSubject();
                    subject.login(new UsernamePasswordToken(username, password));

                    if (subject.isAuthenticated()) {
                            message.setMsg("登录成功");
                    } else {
                        message.setCode(AppConstant.USERNAME_NOTEXIST);
                        message.setMsg("用户名/密码错误");
                    }
                }
            }catch (AuthenticationException ex){
                message.setCode(AppConstant.USERNAME_NOTEXIST);
                message.setMsg("用户名/密码错误");
                ex.printStackTrace();
            }
            finally {
                return new ResponseEntity<Message>(message, HttpStatus.OK);
            }

        }
     
    7 指定认证的策略和多数据源
        <!--shiro的配置-->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <property name="loginUrl" value="/admin/login" />
            <property name="successUrl" value="/admin/home" />
            <property name="unauthorizedUrl" value="/admin/login" />
            <property name="filters">
                <map>
                    <entry key="anno" value-ref="anno"/>
                    <entry key="authc" value-ref="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitionMap">
                <map>
                    <entry key="anon" value="anon"/>
                    <entry key="authc" value="authc"/>
                </map>
            </property>
            <property name="filterChainDefinitions">
                <value>
                    /admin/login=anon
                    /admin/validCode=anon
                    /user/**=authc
                    /role/**=authc
                    /permission/**=authc
                    /**=authc
                </value>
            </property>
        </bean>
        <bean id="authc" class="com.util.filter.MyAccessFilter"/>
        <bean id="anno" class="org.apache.shiro.web.filter.authc.AnonymousFilter"/>
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="authenticator" ref="modelAuthricator"/>
        </bean>
        <bean id="modelAuthricator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <property name="authenticationStrategy" ref="firstSuccess"/>
            <property name="realms">
               <list>
                 <ref local="myRealm"/>
               </list>
            </property>
        </bean>
        <bean id="firstSuccess" class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"/>

    猜你喜欢

    转载自www.cnblogs.com/isme-zjh/p/11428947.html