spring Scurity終於測試OK了,複雜的功能還待深入研究!釋出出來一起探討吧!
spring Scurity終於測試OK了,複雜的功能還待深入研究!釋出出來一起探討吧!
就是因 為研究它,我的個天啦!頭都大了一圈!還待修改完整版!我的目標不是每個專案拿到它就能使用!到時再說啦。。。
雖然只是一個登陸,但裡面的知識真是太廣了!什麼md5 鹽值 加密 生成,cookie 生成序列儲存資料庫,
sessionID防護的一大堆安全,資源許可權分配和保護 等。。。值得一學的框架!
sql 指令碼也在專案一起
專案原始碼下載:http://download.csdn.net/detail/liangrui1988/5916359
官方文件:http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity.html
jar 下載 http://www.springsource.org/download/community
專案圖片:
部分程式碼:
applicationContext-security2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 使用security="none"忽略所有過濾器會提升效能,而是用匿名登入功能可以實現許可權操作的一致性,
具體應用時還需要大家根據實際情況自行選擇了。
<http pattern="/" security="none"/> -->
<http pattern="/image" security="none"/>
<!--entry-point-ref="" 未登入的切入點
servlet-api-provision="true" 預設啟用 儲存沒有登入之前的請求
access-denied-page="" 被攔截之後的頁面-->
<http auto-config="true" entry-point-ref="myAuthenticationEntryPoint"
access-denied-page="/error/page403.jsp" >
<!-- 在配置檔案中使用auto-config="true"就會啟用匿名登入功能。在啟用匿名登入之後,
如果我們希望允許未登入就可以訪問一些資源,可以在進行如下配置。 IS_AUTHENTICATED_ANONYMOUSLY=ROLE_ANONYMOUS-->
<intercept-url pattern="/" access="ROLE_ANONYMOUS"/>
<anonymous username="遊客"/>
<!-- 只要登 陸的使用者都可以訪問專案資源 除了受保護的次源 -->
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<!-- 自定義過濾器 在之前執行 -->
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
<!-- 切換使用者 -->
<custom-filter position="SWITCH_USER_FILTER" ref="switchUserProcessingFilter" />
<!-- 獲取 ip -->
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrentSessionFilter"/>
<!-- 使用者退出 session無效 -->
<logout invalidate-session="true"
logout-url="/j_spring_security_logout" />
<!-- 儲存cookie 儲存使用者名稱密碼多長時間-->
<!--60*60*24*7=604800= 一個星期的秒數 -->
<remember-me key="myApp" token-validity-seconds="604800" data-source-ref="authoritiesData" />
<!-- 使用者登陸 預設跳轉頁面 and 失敗面頁 -->
<form-login default-target-url="/index.jsp" authentication-failure-url="/login.jsp?error=true"/>
<!-- 防禦會話偽造 none,migrateSession和newSession。預設使用的是migrationSession,
<session-management session-fixation-protection="migrateSession"/>-->
<!-- 會話管理 預設30分鐘 ,空閒30分鐘後,自動銷燬
session-authentication-strategy 會話認證策略 session-authentication-strategy-ref="currentControllerStrategy" -->
<session-management invalid-session-url="/login.jsp"
session-authentication-strategy-ref="currentControllerStrategy"/>
<!-- <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management> -->
<!-- 允許同時登陸幾個,如果溢位這個數則報異常 -->
<!-- error-if-maximum-exceeded="true"=不允許把線上使用者踢出去-->
</http>
<!--注意必須放在用來驗證許可權的FilterSecurityInterceptor之後,這樣可以控制當前使用者是否擁有切換使用者的許可權 -->
<beans:bean id="switchUserProcessingFilter"
class="org.springframework.security.web.authentication.switchuser.SwitchUserFilter" autowire="byType">
<beans:property name="targetUrl" value="/manager.jsp"/>
</beans:bean>
<!-- 未登入的切入點 -->
<beans:bean id="myAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.jsp"></beans:property>
</beans:bean>
<!-- 認證管理 -->
<authentication-manager>
<authentication-provider>
<!-- md5加密 -->
<password-encoder hash="md5">
<!-- 鹽值加密 -->
<salt-source user-property="username"/>
</password-encoder>
<!-- 資料庫是自定義的,所以要修改sql查詢語句 使用者資訊 和 許可權資訊 -->
<jdbc-user-service data-source-ref="authoritiesData"
users-by-username-query="select username,password,status as enabled
from user
where username=?"
authorities-by-username-query="select u.username,r.name as authority
from user u
join user_role ur
on u.id=ur.user_id
join role r
on r.id=ur.role_id
where u.username=?"/>
</authentication-provider>
</authentication-manager>
<!-- 過慮攔截器 作用:就是把自定義的資料庫查詢欄位 封裝成security規範 的欄位-->
<beans:bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor" autowire="byType">
<beans:property name="securityMetadataSource" ref="filterInvocationSecurityMetadataSource" />
<beans:property name="authenticationManager" ref="org.springframework.security.authenticationManager"/>
</beans:bean>
<!-- 替換原有功能的切入點 從資料庫裡查詢出資料 資源==角色 注入資料庫源 和查詢結果的sql語句
把受保護的資源(jsp頁面)寫入到資料庫中 需要這樣的配置-->
<beans:bean id="filterInvocationSecurityMetadataSource"
class="accp.util.JdbcFilterInvocationDefinitionSourceFactoryBean">
<beans:property name="dataSource" ref="authoritiesData"/>
<beans:property name="resourceQuery" value="
select re.res_string,r.name
from role r
join resc_role rr
on r.id=rr.role_id
join resc re
on re.id=rr.resc_id
order by re.priority
"/>
</beans:bean>
<!-- 提示資訊 國際化-->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages_zh_CN"/>
</beans:bean>
<!-- 獲取使用者 ip 和使用者繫結,(如是果設了最大會話為1,不用擔心沒登出使用者,無法再登陸!)
這樣在同一個電腦是可以重複登陸, -->
<beans:bean id="concurrentSessionFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry"/>
</beans:bean>
<beans:bean id="sessionRegistry"
class="accp.myFilter.SmartSessionRegistry"/>
<beans:bean id="currentControllerStrategy"
class="accp.myFilter.SmartConcurrentSessionControlStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
<!-- 允許同時登陸幾個,如果溢位這個數則報異常 -->
<!-- error-if-maximum-exceeded="true"=不允許把線上使用者踢出去 -->
<beans:property name="exceptionIfMaximumExceeded" value="true"/>
<beans:property name="maximumSessions" value="1"/>
</beans:bean>
<!-- 記錄日誌 -->
<beans:bean class="accp.myFilter.AuditListener"/>
</beans:beans>
applicationContext-action.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
">
<!--*************************注入services層介面到action******************************-->
<!-- 使用者action 注入services介面 -->
<bean id="userAction" class="accp.action.UserAction">
<property name="services" ref="userServices"/>
<property name="baseUserServices" ref="baseServices"/>
<property name="baseRoleServices" ref="baseServices"/>
</bean>
<!-- registerAction 注入services介面 -->
<bean id="userRegisterAction" class="accp.action.RegisterAction">
<property name="services" ref="userServices"/>
<property name="baseUserServices" ref="baseServices"/>
<property name="baseRoleServices" ref="baseServices"/>
</bean>
<!-- resc action -->
<bean id="rescAction" class="accp.action.RescAction">
<property name="rescServices" ref="rescServices"/>
<property name="baseRescServices" ref="baseServices"/>
<property name="baseRoleServices" ref="baseServices"/>
</bean>
<!-- role action -->
<bean id="roleAction" class="accp.action.RoleAction">
<property name="roleServices" ref="roleServices"/>
<property name="baseRoleServices" ref="baseServices"/>
<property name="baseRescServices" ref="baseServices"/>
</bean>
</beans>
applicationContext-service.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
">
<!--*************************hibernateTemplate******************************-->
<!-- BaseDaoImpl注入 hibernateTemplate-->
<bean id="baseDao" class="accp.dao.imple.BaseDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<!-- RescDaoImpl注入 hibernateTemplate || parent父類是誰 同樣實現的繼承關係-->
<bean id="rescDao" class="accp.dao.imple.RescDaoImpl" parent="baseDao">
<!-- <property name="hibernateTemplate" ref="hibernateTemplate" /> -->
</bean>
<!-- RoleDaoImpl注入 hibernateTemplate-->
<bean id="roleDao" class="accp.dao.imple.RoleDaoImpl" parent="baseDao">
</bean>
<!-- UserDaoImpl注入 hibernateTemplate -->
<bean id="userDao" class="accp.dao.imple.UserDaoImpl" parent="baseDao">
<!-- <property name="hibernateTemplate" ref="hibernateTemplate" /> -->
</bean>
<!--*************************注入dao層介面到services層******************************-->
<!-- baseDao到業務層 parent="baseDao"-->
<bean id="baseServices" class="accp.services.imple.BaseServicesImple" >
<property name="basedao" ref="baseDao"/>
</bean>
<!-- user 方便真接呼叫基本操作類 hibernateTemplate-->
<bean id="userServices" class="accp.services.imple.UserServicesImple">
<property name="userDao" ref="userDao"/>
</bean>
<!-- 角色 -->
<bean id="roleServices" class="accp.services.imple.RoleServicesImple">
<property name="roleDao" ref="roleDao"/>
</bean>
<!-- 資源 -->
<bean id="rescServices" class="accp.services.imple.RescServicesImple">
<property name="rescDao" ref="rescDao"/>
</bean>
</beans>
UserAction.java
package accp.action;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import accp.bean.Role;
import accp.bean.User;
import accp.services.BaseServices;
import accp.services.RoleServices;
import accp.services.UserServices;
import com.opensymphony.xwork2.ActionSupport;
/**
* 使用者管理Action
* @author liangrui
* @qq382453602
*
*/
public class UserAction extends ActionSupport {
private User user;
private List<User> listUser;//使用者集合
private List<Role> roleList;//角色集合
private UserServices services;//使用者介面
private BaseServices<User,Long> baseUserServices;//基本user業務
private BaseServices<Role,Long> baseRoleServices;//基本role業務
private String enabled;//是否生效
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public void setBaseUserServices(BaseServices<User, Long> baseUserServices) {
this.baseUserServices = baseUserServices;
}
public void setBaseRoleServices(BaseServices<Role, Long> baseRoleServices) {
this.baseRoleServices = baseRoleServices;
}
public String getEnabled() {
return enabled;
}
public void setEnabled(String enabled) {
this.enabled = enabled;
}
public UserServices getServices() {
return services;
}
public List<User> getListUser() {
return listUser;
}
public void setListUser(List<User> listUser) {
this.listUser = listUser;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void setServices(UserServices services) {
this.services = services;
}
/*************************login*********************************/
public String logins() throws Exception {
System.out.println("login:"+user.getUsername());
User user2=services.getLogin(user);
if(null==user2){
return "notUser";
}
if("admin".equals(user2.getUsername())){
return "adminPage";
}
System.out.println(user2.getUsername());
return SUCCESS;
}
/************************連線到admin.jsp頁面***********************************/
public String fowaredAdmin() throws Exception {
System.out.println("獲取u p中-------....");
printUserInfo();
System.out.println("轉到admin.jsp面面");
return "adminPage";
}
/************************列印資訊:使用者名稱***********************************/
public void printUserInfo(){
System.out.println("獲取principal 中");
String userName="";
//獲取安全上下文內容
/*SecurityContext sc=SecurityContextHolder.getContext();
Authentication atc=sc.getAuthentication();//獲取認證物件
//獲取主體物件
Object obj=atc.getPrincipal();
if(obj instanceof UserDetails){
//獲取使用者詳細內容物件
UserDetails ud=(UserDetails)obj;
userName=ud.getUsername();
}else{
userName=obj.toString();
}*/
//api 原始碼
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
userName = ((UserDetails)principal).getUsername();
} else {
userName = principal.toString();
}
System.out.println("u: "+userName);
}
/************************hello***********************************/
public String hello() throws Exception {
//printUserInfo();
System.out.println("開始呼叫方法....");
String moedth=services.sayHello("劉備");
System.out.println(moedth);
return "indexs";
}
/************************bye***********************************/
public String bye() throws Exception {
//printUserInfo();
System.out.println("開始呼叫方法..");
String moedth=services.sayBye("張飛");
System.out.println(moedth);
return "indexs";
}
/************************ajax判斷是否有使用者名稱**********************************/
public String ajaxIsUser() throws Exception {
// TODO Auto-generated method stub
System.out.println("ajax來了!開始行動...........: "+user.getUsername());
boolean b=services.getAjaxIsUserName(user.getUsername());
//獲取響應物件
HttpServletResponse response=ServletActionContext.getResponse();
PrintWriter out = response.getWriter();
String bb="";
if(b)bb="true";else bb="false";
System.out.println("b: "+bb);
out.print(bb);
return null;
}
/************************顯示所有使用者資訊**********************************/
public String showUserInfo() throws Exception {
listUser=baseUserServices.getAll(new User());
return "showUser";
}
/**************************刪除使用者****************************************/
public String deleteUser() throws Exception {
try {
System.out.println("du: id "+user.getId());
baseUserServices.delete(user);
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "deleteUserOK";
}
/**************************修改使用者 查詢資訊 並顯示************************************/
public String updateUser() throws Exception {
try {
user=baseUserServices.getTInId(user,user.getId());
//查詢角色
System.out.println("開始查詢role----");
roleList=baseRoleServices.getAll(new Role());
} catch (Exception e) {
return "error";
}
return "updateEidt";
}
/**************************儲存修改後的使用者************************************/
public String updateSave() throws Exception {
try {
Md5PasswordEncoder md5 = new Md5PasswordEncoder();
String passwordMD5=md5.encodePassword(user.getPassword(), user.getUsername());
user.setPassword(passwordMD5);
//封裝角色集合
Set<Role> rolesSet=new HashSet<Role>();
//取到許可權的物件
Set set=user.getRoles();
Iterator it=set.iterator();
while(it.hasNext()){
//根據id查詢物件
Long roleID=Long.valueOf(it.next().toString());
//System.out.println(roleID);
Role role=baseRoleServices.getTInId(new Role(),roleID);
rolesSet.add(role);
}
user.setRoles(rolesSet);//將角色加入使用者物件裡
//是否生效
if(null==enabled){
user.setStatus(0);
}else{
user.setStatus(1);
}
System.out.println(user.getId()+user.getUsername()+user.getPassword());
//通過傳過來的角色id獲取角色物件
baseUserServices.update(user);
} catch (Exception e) {
return "error";
}
return "updateOk";
}
/*********************通對物件條件查詢****************************/
public String searchUser() throws Exception {
if(null!=user){
listUser=baseUserServices.getTInName(user);
}
return "showUser";
}
/*************************顯示所有角色*************************/
public String displayRole() throws Exception {
System.out.println("開始查詢role----");
roleList=baseRoleServices.getAll(new Role());
return "addUsersAndShowRole";
}
}
BaseServices.java
package accp.services;
import java.io.Serializable;
import java.util.List;
import accp.dao.BaseDao;
import accp.dao.imple.BaseDaoImpl;
/**
*
* @author liangrui
* @qq 382453602
* @param <T> 泛型類
* @param <PK> 主健
* 基本資料操作 業務層
* 都 可以來這時呼叫 增、刪、改、查
*/
public interface BaseServices<T,PK extends Serializable > /* extends BaseDao<T,PK>*/{
public PK save(T t);
public void delete(T t);
public void update(T t);
/***根據物件 獲取物件集合**/
public List<T> getAll(T t);
/***通過id 獲取物件集合**/
public T getTInId(T t,PK pk);
/***根據名稱 獲取物件集合**/
public List<T> getTInName(T t) throws Exception;
}
BaseDao.java
package accp.dao;
import java.io.Serializable;
import java.util.List;
/**
*
* @author liangrui
* @qq 382453602
* @param <T> 泛型類
* @param <PK> 主健
* 基本資料操作 代業務層 資料層 什麼層層的
* 都 可以來這時呼叫 增、刪、改、查
*/
public interface BaseDao<T,PK extends Serializable> {
public PK save(T t);
public void delete(T t);
public void update(T t);
/***根據物件 獲取物件集合**/
public List<T> getAll(T t);
/***通過id 獲取物件集合**/
public T getTInId(T t,PK pk);
/***根據物件條件 獲取物件集合**/
public List<T> getTInName(T t) throws Exception;
}
BaseDaoImpl.java
package accp.dao.imple;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import accp.util.GenericsUtils;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import accp.dao.BaseDao;
public class BaseDaoImpl<T,PK extends Serializable> extends HibernateDaoSupport implements BaseDao<T, PK> {
private Class clas ;
//得到類
public BaseDaoImpl(){
/**
* 得到泛型的類
* 即 BaseDaoImpl<Users> 得到Users
* 類的超類>>>現在型別的 論據
*/
clas = GenericsUtils.getSuperClassGenricType(getClass());
}
public PK save(T t) {
//System.out.println("T:" +t.getClass().getSimpleName());
return (PK) this.getHibernateTemplate().save(t);
}
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
public void update(T t) {
this.getHibernateTemplate().update(t);
}
public List<T> getAll(T t) {
// 根據物件 得到對像集合
String objName=t.getClass().getSimpleName();//得到 物件名
//System.out.println(objName);
return this.getHibernateTemplate().find("from "+objName);
}
/********************通過id獲取物件****************************/
public T getTInId(T t,PK pk) {
/*String objName=clas.getClass().getSimpleName();//得到 物件名
System.out.println(clas +" : "+objName +" PK: "+pk);*/
return (T) this.getHibernateTemplate().get(t.getClass(),pk);
}
/************************************************************
*通過傳送過來的物件值做為條件 查詢
*並得到反回的集合
************************************************************/
@SuppressWarnings("unchecked")
public List<T> getTInName(T t) throws Exception {
//得到物件的欄位 就是查詢條件
String objName=t.getClass().getSimpleName();
//拼接條件
StringBuffer hql=new StringBuffer("from "+objName);
hql.append(" where 1=1");
Field [] objFileds =t.getClass().getDeclaredFields();
Object [] SqlParamter = null;
List<Object> SqlParamters=new ArrayList<Object>();
for(int i=0;i<objFileds.length;i++){
Field fileld=objFileds[i];
fileld.setAccessible(true);//可進入的
Object objT=fileld.get(t);
//得到值
if(!"".equals(objT)&&null!=objT){
if(fileld.getName().equals("id")){
if(Integer.parseInt(objT.toString())>0){//不為0
//如果是id則 則直接處理
return this.getHibernateTemplate().
find("from "+objName +" where id="+objT);
}
}else if(objT instanceof Set){//如果是集合
//可以斷續追加物件 條件
}else{
System.out.println(fileld.getName()+" value: "+objT);
hql.append(" and "+fileld.getName()+"=?");
SqlParamters.add(objT);
//SqlParamter[i]=objT;
}
}
}
//如果沒有任條件的物件 ,則返回所有資料
if(null==SqlParamters||SqlParamters.size()<=0){
return this.getHibernateTemplate().find("from "+objName);
}
//把集合中的資料 轉入陣列
SqlParamter=new Object[SqlParamters.size()];
for(int i=0;i<SqlParamters.size();i++){
SqlParamter[i]=SqlParamters.get(i);
}
//excute
return this.getHibernateTemplate().find(hql.toString(),SqlParamter);
}
}
package accp.services.imple;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import accp.bean.Resc;
import accp.bean.Role;
import accp.bean.User;
import accp.dao.UserDao;
import accp.dao.imple.BaseDaoImpl;
import accp.services.UserServices;
/**
*
* @author liangrui
* 基本操做可以呼叫BaseDao時的方法
* 使用者業務處理層
* extends BaseDaoImpl<User,Integer>
*
*/
public class UserServicesImple implements UserServices {
private UserDao userDao;//使用者資料層介面
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public String sayHello(String name) {
System.out.println("進來了!!!");
return "hello:"+name;
}
public String sayBye(String name) {
// TODO Auto-generated method stub
return "bay:"+name;
}
/**************ajax判斷是否有重複名字*********************/
public boolean getAjaxIsUserName(String name) {
return userDao.getAjaxIsUserName(name);
}
/***************************使用者登陸***************************/
public User getLogin(User u) {
// TODO Auto-generated method stub
//List<User> list=super.getAll(u);
List list=userDao.getAll(u);
if(null==list||list.size()<=0){
return null;
}else {
return (User) list.get(0);
}
}
/***register***/
public User saveUser(User u){
try {
userDao.save(u);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return u;
}
}
struts_user.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="userPackage" namespace="/" extends="struts-default">
<!-- 使用者 action -->
<action name="user_*" class="userAction" method="{1}" >
<result name="success">/userPage.jsp</result>
<result name="adminPage">/admin.jsp</result>
<result name="indexs">/index.jsp</result>
<result name="ok">/userReg/ok.jsp</result>
<result name="showUser">/admin/userAuthorities.jsp</result>
<result name="error">/userReg/error.jsp</result>
<result name="updateEidt">/userReg/updateEdit.jsp</result>
<!-- -->
<result name="deleteUserOK" type="redirectAction">user_showUserInfo.action</result>
<result name="updateOk" type="redirectAction">user_showUserInfo.action</result>
<result name="addUsersAndShowRole">/userReg/regsiter.jsp</result>
</action>
<action name="users_*" class="userRegisterAction" method="{1}">
<result name="ok">/userReg/ok.jsp</result>
<result name="error">/userReg/error.jsp</result>
<result name="input">/userReg/regsiter.jsp</result>
<!--防止表單重提交 -->
<result name="invalid.token">/userReg/alert.jsp</result>
<interceptor-ref name="token"/>
<interceptor-ref name="defaultStack"/>
</action>
</package>
</struts>
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<style type="text/css">
.errorhide{display: none;}
.error{display: block;}
</style>
</head>
<body>
<div style="width:1200px; text-align: center; margin-top: 150px;">
<div class="error${param.error==true ? '' : 'hide'}">
登陸失敗<br>
<font color="red">${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}</font><br/>
</div>
<form action="${pageContext.request.contextPath}/j_spring_security_check" method="post" style="width:260px;text-align:center;">
<fieldset>
<legend>登陸</legend>
使用者: <input type="text" name="j_username" style="width:150px;" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}"/><br />
密碼: <input type="password" name="j_password" style="width:150px;" /> <br />
<input type="checkbox" name="_spring_security_remember_me"/>一週之內不必登陸<br />
<input type="submit" value="登陸"/>
<input type="reset" value="重置"/>
</fieldset>
</form>
<br/>
<a HREF="${pageContext.request.contextPath}/admin.jsp">ADMIN.JSP</a> <br/>
<a HREF="${pageContext.request.contextPath}/userPage.jsp">userPage.jsp</a> <br/>
<a href="j_spring_security_logout">登出使用者</a>
</div>
</body>
</html>
主要程式碼就這些吧!有興趣的朋友可以下載原始碼,全部貼出來,累死個人
相關文章
- C#9.0 終於來了,您還學的動嗎? 帶上VS一起解讀吧!C#
- 探討一個比較複雜的查詢
- 深入探討 Chrome iOS 版測試及釋出流程ChromeiOS
- 關於複雜任務與異常處理的設計模式探討!設計模式
- 複雜查詢還是直接寫sql吧SQL
- VSCode 的 Live Share 功能終於來了VSCode
- 關於enq: TX - index contention 等待的探討與測試ENQIndex
- 一起探討JavaScript的物件JavaScript物件
- 一種測試方向的探討-基於模型測試調研引發的思考-1模型
- 一種測試方向的探討-基於模型測試調研引發的思考-4模型
- 請問板橋老師:Jdon Framework開發測試包能否釋出出來Framework
- 「譯」一起探討 JavaScript 的物件JavaScript物件
- 還在用Jenkins?試試Gitlab的CI/CD功能吧JenkinsGitlab
- 盼望著,盼望著。它終於來了!!!剪輯Windows PC測試版!Windows
- C#9.0 終於來了,您還學的動嗎? 帶上VS一起解讀吧!(應該是全網第一篇)C#
- 深入探討 Java Spring 框架事務註釋JavaSpring框架
- 關於dwr的測試時,bean複雜資料的輸入Bean
- 關於如何防止重複簽到的技術探討
- Spring 下,關於動態資料來源的事務問題的探討Spring
- Spring Cloud分散式事務終極解決方案探討SpringCloud分散式
- 來和餓了麼大前端一起工作吧前端
- 探討Morest在RESTful API測試的行業實踐RESTAPI行業
- Tessy—支援複雜場景測試的單元整合測試工具
- 寫了個連線池的類,和大家一起探討,歡迎交流
- StreamPark 2.0.0 重磅釋出,首個 Apache 版本終於來了!Apache
- 它來了它終於來了- Beego 1.12.2Go
- VS Code Day,終於來了!
- 探討Spring框架使用真相Spring框架
- 功能驅動開發FDD的探討
- 非技術探討:文章定時釋出功能如何實現
- 終於要來了!蘋果新產品釋出時間曝光蘋果
- 你要的 Helm Chart 應用金絲雀釋出終於來了!
- 關於mongo原子操作的探討Go
- 關於identity列的探討IDE
- 網際網路時代,自動化測試勢不可擋,你還在討論如何做好功能測試?
- spring IOC容器實現探討Spring
- 用 JMeter 做複雜介面測試遇到的問題JMeter
- 如何使用spring測試模組測試請求功能Spring