zoukankan      html  css  js  c++  java
  • springmvc拦截器实现登录验证

    首先创建一个实体类:

    Customer: 

     1 package com.petcare.pojo.base;
     2 
     3 import java.sql.Date;
     4 import java.sql.Timestamp;
     5 
     6 /**
     7  * Created by frank on 2017/5/7.
     8  */
     9 
    10 public class Customer {
    11     private Long customerId;
    12     private String account;
    13     private String passwd;
    14     private String customerName;
    15     private String wechat;
    16     private String mobile;
    17 
    18     public Long getCustomerId() {
    19         return customerId;
    20     }
    21     public void setCustomerId(Long customerId) {
    22         this.customerId = customerId;
    23     }
    24     public String getAccount() {
    25         return account;
    26     }
    27     public void setAccount(String account) {
    28         this.account = account;
    29     }
    30     public String getPasswd() {
    31         return passwd;
    32     }
    33     public void setPasswd(String passwd) {
    34         this.passwd = passwd;
    35     }
    36     public String getCustomerName() {
    37         return customerName;
    38     }
    39     public void setCustomerName(String customerName) {
    40         this.customerName = customerName;
    41     }
    42     public String getWechat() {
    43         return wechat;
    44     }
    45     public void setWechat(String wechat) {
    46         this.wechat = wechat;
    47     }
    48     public String getMobile() {
    49         return mobile;
    50     }
    51     public void setMobile(String mobile) {
    52         this.mobile = mobile;
    53     }
    54 
    55     @Override
    56     public boolean equals(Object o) {
    57         if (this == o) return true;
    58         if (o == null || getClass() != o.getClass()) return false;
    59 
    60         Customer customer = (Customer) o;
    61 
    62         if (customerId != customer.customerId) return false;
    63         if (account != null ? !account.equals(customer.account) : customer.account != null) return false;
    64         if (passwd != null ? !passwd.equals(customer.passwd) : customer.passwd != null) return false;
    65         if (customerName != null ? !customerName.equals(customer.customerName) : customer.customerName != null)
    66             return false;
    67         if (wechat != null ? !wechat.equals(customer.wechat) : customer.wechat != null) return false;
    68         if (mobile != null ? !mobile.equals(customer.mobile) : customer.mobile != null) return false;
    69         if (homephone != null ? !homephone.equals(customer.homephone) : customer.homephone != null) return false;
    70         if (customerSex != null ? !customerSex.equals(customer.customerSex) : customer.customerSex != null)
    71             return false;
    72         if (customerBirth != null ? !customerBirth.equals(customer.customerBirth) : customer.customerBirth != null)
    73             return false;
    74         if (address != null ? !address.equals(customer.address) : customer.address != null) return false;
    75         if (createSeid != null ? !createSeid.equals(customer.createSeid) : customer.createSeid != null) return false;
    76         if (createTime != null ? !createTime.equals(customer.createTime) : customer.createTime != null) return false;
    77         if (updateTime != null ? !updateTime.equals(customer.updateTime) : customer.updateTime != null) return false;
    78 
    79         return true;
    80     }
    81 
    82     @Override
    83     public int hashCode() {
    84         int result = (int) (customerId ^ (customerId >>> 32));
    85         result = 31 * result + (account != null ? account.hashCode() : 0);
    86         result = 31 * result + (passwd != null ? passwd.hashCode() : 0);
    87         result = 31 * result + (customerName != null ? customerName.hashCode() : 0);
    88         result = 31 * result + (wechat != null ? wechat.hashCode() : 0);
    89         result = 31 * result + (mobile != null ? mobile.hashCode() : 0);
    90         result = 31 * result + (homephone != null ? homephone.hashCode() : 0);
    91         result = 31 * result + (customerSex != null ? customerSex.hashCode() : 0);
    92         result = 31 * result + (customerBirth != null ? customerBirth.hashCode() : 0);
    93         result = 31 * result + (address != null ? address.hashCode() : 0);
    94         result = 31 * result + (createSeid != null ? createSeid.hashCode() : 0);
    95         result = 31 * result + (createTime != null ? createTime.hashCode() : 0);
    96         result = 31 * result + (updateTime != null ? updateTime.hashCode() : 0);
    97         return result;
    98     }
    99 }

    controller层;

     1 @Controller
     2 public class LoginController {
     3 
     4     private Logger log = LoggerFactory.getLogger(getClass());
     5 
     6     public static final AjaxResponse ACCOUNT_NOT_EXIST = new AjaxResponse(-100101, "账号不存在");
     7     public static final AjaxResponse PASSWORD_NOT_PASSED = new AjaxResponse(-100102, "您输入密码错误");
     8     public static final AjaxResponse SYSTEM_BUSY = new AjaxResponse(-100000, "系统繁忙");
     9     public static final AjaxResponse ACCOUNT_LOCKED = new AjaxResponse(-100103, "您的帐号被锁定");
    10 
    11 
    12     @Autowired
    13     private CustomerService customerService;
    14 
    15     @RequestMapping(value = "/login", method = RequestMethod.GET)
    16     public  String loginPage(){
    17         return  "/login";
    18     }
    19 
    20     @RequestMapping(value = "/login", method = RequestMethod.POST)
    21     @ResponseBody
    22     public  AjaxResponse login(String u , String p, HttpSession session){
    23 
    24         // 封装令牌
    25         UsernamePasswordToken token = new UsernamePasswordToken(u,p);
    26         Subject subject = null;
    27         try {
    28             subject = SecurityUtils.getSubject();
    29             // 用令牌登陆,如果登陆失败,则抛出异常
    30             subject.login(token);
    31             token.clear();
    32         } catch (AccountNotExistException ex) {
    33             return ACCOUNT_NOT_EXIST;
    34         } catch (PasswordWrongException ex) {
    35             return PASSWORD_NOT_PASSED;
    36         }
    37         catch (AccountLockedException ex) {
    38             return ACCOUNT_LOCKED;
    39         }
    40         catch (Exception ex) {
    41             log.error("login error happend.", ex);
    42             return SYSTEM_BUSY;
    43         }
    44 
    45         Customer c = customerService.getBaseCustomer(u);
    46 
    47         // 保存会话
    48         session.setAttribute(Const.SESSION_SUBJECT, subject); // shiro已登录用户
    49         session.setAttribute(Const.SESSION_USER_KEY,c );// 登陆用户
    50         return AjaxResponse.OK;
    51 
    52     }
    53 }

    UsernamePasswordToken源码:

    package org.apache.shiro.authc;
    /**
         * Constructs a new UsernamePasswordToken encapsulating the username and password submitted
         * during an authentication attempt, with a <tt>null</tt> {@link #getHost() host} and a
         * <tt>rememberMe</tt> default of <tt>false</tt>.
         *
         * @param username the username submitted for authentication
         * @param password the password character array submitted for authentication
         */
        public UsernamePasswordToken(final String username, final char[] password) {
            this(username, password, false, null);
        }
    
        /**
         * Constructs a new UsernamePasswordToken encapsulating the username and password submitted
         * during an authentication attempt, with a <tt>null</tt> {@link #getHost() host} and
         * a <tt>rememberMe</tt> default of <tt>false</tt>
         * <p/>
         * <p>This is a convience constructor and maintains the password internally via a character
         * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
         * in your code could have possible security implications as noted in the class JavaDoc.</p>
         *
         * @param username the username submitted for authentication
         * @param password the password string submitted for authentication
         */
        public UsernamePasswordToken(final String username, final String password) {
            this(username, password != null ? password.toCharArray() : null, false, null);
        }

     getSubject()源码:

     1 package org.apache.shiro;
     2 
     3 import org.apache.shiro.mgt.SecurityManager;
     4 import org.apache.shiro.subject.Subject;
     5 import org.apache.shiro.util.ThreadContext;
     6 
     7 
     8 /**
     9  * Accesses the currently accessible {@code Subject} for the calling code depending on runtime environment.
    10  *
    11  * @since 0.2
    12  */
    13 public abstract class SecurityUtils {
    14 
    15     /**
    16      * ONLY used as a 'backup' in VM Singleton environments (that is, standalone environments), since the
    17      * ThreadContext should always be the primary source for Subject instances when possible.
    18      */
    19     private static SecurityManager securityManager;
    20 
    21     /**
    22      * Returns the currently accessible {@code Subject} available to the calling code depending on
    23      * runtime environment.
    24      * <p/>
    25      * This method is provided as a way of obtaining a {@code Subject} without having to resort to
    26      * implementation-specific methods.  It also allows the Shiro team to change the underlying implementation of
    27      * this method in the future depending on requirements/updates without affecting your code that uses it.
    28      *
    29      * @return the currently accessible {@code Subject} accessible to the calling code.
    30      * @throws IllegalStateException if no {@link Subject Subject} instance or
    31      *                               {@link SecurityManager SecurityManager} instance is available with which to obtain
    32      *                               a {@code Subject}, which which is considered an invalid application configuration
    33      *                               - a Subject should <em>always</em> be available to the caller.
    34      */
    35     public static Subject getSubject() {
    36         Subject subject = ThreadContext.getSubject();
    37         if (subject == null) {
    38             subject = (new Subject.Builder()).buildSubject();
    39             ThreadContext.bind(subject);
    40         }
    41         return subject;
    42     }
    43 }

    login源码:

     1 /**
     2      * Performs a login attempt for this Subject/user.  If unsuccessful,
     3      * an {@link AuthenticationException} is thrown, the subclass of which identifies why the attempt failed.
     4      * If successful, the account data associated with the submitted principals/credentials will be
     5      * associated with this {@code Subject} and the method will return quietly.
     6      * <p/>
     7      * Upon returning quietly, this {@code Subject} instance can be considered
     8      * authenticated and {@link #getPrincipal() getPrincipal()} will be non-null and
     9      * {@link #isAuthenticated() isAuthenticated()} will be {@code true}.
    10      *
    11      * @param token the token encapsulating the subject's principals and credentials to be passed to the
    12      *              Authentication subsystem for verification.
    13      * @throws org.apache.shiro.authc.AuthenticationException
    14      *          if the authentication attempt fails.
    15      * @since 0.9
    16      */
    17     void login(AuthenticationToken token) throws AuthenticationException;

    clear源码:

     1 /*--------------------------------------------
     2     |               M E T H O D S               |
     3     ============================================*/
     4 
     5     /**
     6      * Clears out (nulls) the username, password, rememberMe, and inetAddress.  The password bytes are explicitly set to
     7      * <tt>0x00</tt> before nulling to eliminate the possibility of memory access at a later time.
     8      */
     9     public void clear() {
    10         this.username = null;
    11         this.host = null;
    12         this.rememberMe = false;
    13 
    14         if (this.password != null) {
    15             for (int i = 0; i < password.length; i++) {
    16                 this.password[i] = 0x00;
    17             }
    18             this.password = null;
    19         }
    20 
    21     }

    四个异常类,此时产生一个疑问,怎么验证数据那,此时需要一个配置我文件spring-shiro:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
     4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
     5     xmlns:context="http://www.springframework.org/schema/context"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
     7     default-lazy-init="true">
     8 
     9     <!-- 安全管理器 -->
    10     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    11         <property name="realm" ref="shiroDBRealm" />
    12         <!--<property name="cacheManager" ref="cacheManager" />-->
    13     </bean>
    14     <!--<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />-->
    15 
    16     <!-- shiro过滤器 -->
    17     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    18         <property name="securityManager" ref="securityManager" />
    19         <property name="loginUrl" value="/login.action" />
    20         <property name="successUrl" value="/welcome.action" />
    21         <property name="unauthorizedUrl" value="/login.action" />
    22         <property name="filterChainDefinitions">
    23             <value>
    24             </value>
    25         </property>
    26     </bean>
    27     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    28 
    29     <!-- 验证数据类 -->
    30     <bean id="shiroDBRealm" class="com.petcare.admin.security.shiro.ShiroDBRealm" />
    31 
    32 </beans>

    类shiroDBRealm:

     1 /**
     2  * Specl.com Inc.
     3  * Copyright (c) 2010-2011 All Rights Reserved.
     4  */
     5 package com.petcare.admin.security.shiro;
     6 
     7 import com.petcare.admin.service.CustomerService;
     8 import com.petcare.pojo.base.Customer;
     9 import org.apache.commons.lang.StringUtils;
    10 import org.apache.shiro.authc.*;
    11 import org.apache.shiro.authz.AuthorizationInfo;
    12 import org.apache.shiro.authz.SimpleAuthorizationInfo;
    13 import org.apache.shiro.realm.AuthorizingRealm;
    14 import org.apache.shiro.subject.PrincipalCollection;
    15 import org.slf4j.Logger;
    16 import org.slf4j.LoggerFactory;
    17 
    18 import javax.annotation.Resource;
    19 
    20 
    21 
    22 /**
    23  * 权限数据访问类。
    24  *
    25  *
    26  */
    27 public class ShiroDBRealm extends AuthorizingRealm {
    28 
    29     private Logger log = LoggerFactory.getLogger(this.getClass());
    30 
    31     /**
    32      * 账号访问层。
    33      */
    34     @Resource
    35     private CustomerService customerService;
    36 
    37     /**
    38      * 认证方法。
    39      */
    40     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    41 
    42         log.debug("do authentication ,token data [{}]", authcToken);
    43 
    44         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    45 
    46         if (token.getUsername() == null) {
    47             return null;
    48         }
    49 
    50         // 根据账户名获得账户
    51          Customer customer = customerService.getBaseCustomer(token.getUsername());
    52 
    53         // 当账号密码不存在
    54         if (customer == null) {
    55             log.debug("customer not exist.");
    56             throw new AccountNotExistException();
    57         }
    58 
    59         // 当密码错误
    60         if (!StringUtils.equals(customer.getPasswd(), new String(token.getPassword()))) {
    61             log.debug("password not equals.");
    62             throw new PasswordWrongException();
    63         }
    64 
    65 //        if(customer.getIsDelete()==1) {
    66 //            log.debug("customer is locked.");
    67 //            throw new AccountLockedException();
    68 //        }
    69         return new SimpleAuthenticationInfo(customer.getAccount(), customer.getPasswd(), getName());
    70     }
    71 
    72     /**
    73      * 授权方法。
    74      */
    75     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    76 
    77         log.debug("do authortization , principals data [{}]", principals);
    78 
    79 //        String username = (String) principals.fromRealm(getName()).iterator().next();
    80 //
    81 //        // 根据账户名获得账户
    82 //         CustomerAccount account = customerAccountDao.getAccountByUsername(username);
    83 //
    84 //        if (account == null) {
    85 //            log.debug("account not exist.");
    86 //            throw new AccountNotExistException();
    87 //        }
    88 
    89         // 封装授权信息
    90         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    91         // 将用户的角色字符,进行授权
    92 //        info.addRoles(account.getRoleStringList());
    93         // 将用户的权限字符,进行授权
    94 //        info.addStringPermissions(account.getPermissionStringList());
    95         return info;
    96     }
    97 }

    web.xml:

    有待修改:

     1     <!-- listeners -->
     2     <listener>
     3         <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
     4     </listener>
     5     <listener>
     6         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
     7     </listener>
     8 
     9 
    10     <!-- shiro,find spring bean by filter name is 'shiroFilter' -->
    11     <filter>
    12         <filter-name>shiroFilter</filter-name>
    13         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    14         <init-param>
    15             <param-name>targetFilterLifecycle</param-name>
    16             <param-value>true</param-value>
    17         </init-param>
    18     </filter>
  • 相关阅读:
    OpenWAF学习笔记(四)—— API-接入规则
    OpenWAF学习笔记(三)—— 调用API时403?
    OpenWAF学习笔记(二)—— 入门
    OpenWAF学习笔记(一)—— 安装
    SQL Server获取数据库表、视图、存储过程数量及名称
    获取真实IP地址——代理背后的终端ip地址
    博客园美化-添加看板娘
    强密码验证-大小写字母、数字、特殊字符、长度
    【c++面试总结】
    【一天一道算法题】 两个字符串相乘
  • 原文地址:https://www.cnblogs.com/xiaonantianmen/p/9446035.html
Copyright © 2011-2022 走看看