用戶登錄功能實現(shiro)


一  配置shiro的filter實現URL級別權限控制  

登錄流程:應用程序-->Subject(就是shiro管理的用戶)-->securityManger(安全管理器,shiro權限控制的核心)--Realm(應用程序和安全數據之間連接器)--安全數據---->SecurityManager(底層判斷)---->Suject--->application code

在編寫程序是操作Subject方法,調用底層的SucurityManger安全管理器進行管理,並通過Realm這個應用程序和安全數據之間的連接器的對象,來完成權限控制讀取安全數據.

1.配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <!-- spring配置文件位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- spring核心監聽器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
<!-- shiro的filter -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- struts2 過濾器 -->
    <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>*.action</url-pattern>
    </filter-mapping>
</web-app>
View Code

2.配置application.xml    

anon 未認證可以訪問   authc 認證后可以訪問     perms 需要特定權限才能訪問     roles 需要特定角色才能訪問

user 需要特定用戶才能訪問    port 需要特定端口才能訪問    reset 根據指定 HTTP 請求訪問才能訪問

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa 
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    <!-- 配置shiro的核心Filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 配置安全管理器 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 未認證,跳轉到哪個頁面  -->
        <property name="loginUrl" value="/login.html"/>
        <!-- 登錄頁面頁面 -->
        <property name="successUrl" value="/index.html"/>
        <!-- 認證后,沒有權限跳轉頁面 -->
        <property name="unauthorizedUrl" value="/unauthorized.html" />
        <!-- shiro URL控制過濾器規則  -->
        <property name="filterChainDefinitions">
            <value>
                /login.html* =anon
                /user_login.action=anon  <!-- 登錄時在認證前訪問 -->
                /validatecode.jsp*=anon  <!-- anon 未認證可訪問.authc認證后可訪問-->
                /css/**=anon
                /js/**=anon
                /images/**=anon
                /services/**=anon
                /**=authc
            </value>
        </property>
    </bean>
        <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"></property>
    </bean>
    <!-- shiro的后處理器 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor">
    
    </bean>
</beans>
View Code

3.在登錄界面,form表單補全,並提交.

<form class="form-horizontal" id="loginform" name="loginform" method="post" action="user_login.action">
<a href="javascript:$('#loginform').submit();" id="loginform" name="loginform" >立即登錄</a>

4.在UserAction編寫login方法

package cn.itcast.bos.web.action.system;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.web.action.common.BaseAction;
@Namespace("/")
@Controller
@ParentPackage("json-default")
@Scope("prototype")
public class UserAction extends BaseAction<User>{
    @Action(value="user_login",results={@Result(type="redirect",name="success",location="index.html")
    ,@Result(name="login",type="redirect",location="login.html")})
    public String login(){
        //用戶名和密碼都保存在model中
        //基於shiro實現登錄
        Subject subject =  SecurityUtils.getSubject();
        //用戶名和密碼保存到token中
        AuthenticationToken token= new UsernamePasswordToken(model.getUsername(),model.getPassword());
        try {
            //如果正常登錄,表示沒有異常.登陸成功
            subject.login(token);
            return SUCCESS;
        } catch (Exception e) {
            //如果異常,表示登錄失敗,重新跳轉到登錄頁面
            e.printStackTrace();
            return LOGIN;
        }
    }
}
View Code

5.定義Realm,實現認證方法.   

package cn.itcast.bos.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
//加入Spring管理的注解,bean管理.
@Component("bosRealm")
public class BosRealm extends AuthorizingRealm{
   private UserService  userService ;
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        System.out.println("授權...");
        return null;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("認證...");
        //轉換token
        UsernamePasswordToken UsernamePasswordToken=(UsernamePasswordToken) token;
        //根據用戶名查詢用戶信息
        User user = userService.findByUsername(UsernamePasswordToken.getUsername());
        if(user==null){
            //用戶名不存在
            //參數一:期望登陸后保存在subject中的信息
            //參數二:密碼
            //參數三:realm的名稱
            //return new SimpleAuthenticationInfo(user,null,getName());
            return null;
        }else{
            //用戶名存在
            //當返回密碼時,securityManager安全管理器會自動比較與用戶傳過來的密碼
            //如果一致,登陸成功,如果不一致,報密碼錯誤異常
            return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
        }
        
    }

}
View Code

6.調用service與dao

package cn.itcast.bos.service.system;

import cn.itcast.bos.domain.system.User;

public interface UserService {

    public User findByUsername(String username);
}
package cn.itcast.bos.service.system.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.itcast.bos.dao.system.UserRepository;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
@Service
@Transactional
public class UserServiceImpl implements UserService {
    private UserRepository userRepository ;
    @Override
    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

}
package cn.itcast.bos.dao.system;

import org.springframework.data.jpa.repository.JpaRepository;

import cn.itcast.bos.domain.system.User;

public interface UserRepository extends JpaRepository<User, Integer>{

    public User findByUsername(String username);
    
}

org.apache.shiro.authc.UnknownAccountException 當認證方法直接返回 null,說明用戶名不存在

org.apache.shiro.authc.IncorrectCredentialsException 當返回對象中密碼與用戶輸入密碼不一致 密碼錯誤

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM