学习spring-Security3.0

spring-Security的作用就不多说了,大家都懂的!


假设 一个项目有2个权限一个是管理员admin,一个是普通用户user。有些网页,action是只能admin去访问,user不能访问。

有一些解决方法是选择将user访问不到的连接影藏掉,但是这样不能彻底解决,

假如我知道连接可以收到去敲连接访问到,那又有一种办法在每个方法前面加判断,这些介绍一种spring的安全框架spring-Security

spring-Security 还有很多功能是我还没发现的,因为项目中用到了权限判断就学习了下,记录下来,不对的地方希望大虾能提成来指导!


在项目中一般都已经搭好框架了的,主要在这个前提下 我说一下我学习到的!

我先建立了个测试环境(struts2 的 把spring 和 spring-Security3.0的jar导进去,为方便就没加数据库)

spring-Security下载地址(官方的有jar,demo) 点击打开链接   


我建立了一个403.jsp 目的是让没有权限的用户跳到这里(里面没什么内容,就不贴代码了(内容:403.jsp 做了一个标识))

一个login.jsp  用来登录

一个welcome.jsp,namespace="/admin" 的struts2的包下的atestAction.action  只能admin访问

一个/welcomeUser.jsp  能让admin和user访问

一个namespace="/user" 的struts2的包下的utestAction.action 只能user 访问


项目图



web.xml

主要有spring的listener   struts2的filter  和 spring-Security  filter 过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext*.xml</param-value>
	</context-param>

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

	<!-- spring-Security 过滤器 -->
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>
			org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springSecurityFilterChain</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>/*</url-pattern>  
    </filter-mapping> 

	<welcome-file-list>
		<welcome-file>login.jsp</welcome-file>
	</welcome-file-list>
</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>

	<package name="default" extends="struts-default">
		 <action name="loginAction" class="com.yeshun.action.UserAction" method="login">
			<result name="success">/index.jsp</result>
			<result name="error">/403.jsp</result>
		 </action>
	</package>
	
	<package name="admin" extends="struts-default" namespace="/admin">
		 <action name="atestAction" class="com.yeshun.action.TestAction" method="admin">
			<result name="success">/welcome.jsp</result>
		 </action>
	</package>
	
	<package name="user" extends="struts-default" namespace="/user">
		 <action name="utestAction" class="com.yeshun.action.TestAction" method="user">
			<result name="success">/welcomeUser.jsp</result>
		 </action>
	</package>

</struts>    

主要spring-Security的配置文件    applicationContext-security.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.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<http access-denied-page="/403.jsp" use-expressions="true"><!-- 当访问被拒绝时,会转到403.jsp -->
		<intercept-url pattern="/css/**" filters="none" />
		<intercept-url pattern="/img/**" filters="none" />
		<intercept-url pattern="/js/**" filters="none" />
                <!-- 一般项目中都会用到 css,img,js等文件    那么在这些路径下的文件就不需要设定权限   filters="none" 就是不需要权限   -->
                <intercept-url pattern="/login.jsp" filters="none" />
		<intercept-url pattern="/welcome.jsp" access="hasRole('ROLE_ADMIN')" />
		<intercept-url pattern="/admin/*.action" access="hasRole('ROLE_ADMIN')" />
		<intercept-url pattern="/welcomeUser.jsp" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')" />
		<intercept-url pattern="/user/*.action" access="hasRole('ROLE_USER')" />
        <!-- hasRole('ROLE_ADMIN') 表示只能ROLE_ADMIN权限可以访问 -->
        <!-- hasRole('ROLE_USER') 表示只能ROLE_USER权限可以访问 -->
        <!-- hasAnyRole('ROLE_ADMIN','ROLE_USER') 表示只能ROLE_ADMIN,ROLE_USER权限可以访问 -->
        <!-- hasRole只能指定一个权限,hasAnyRole可以指定多个 -->
                <form-login login-page="/login.jsp"
			authentication-failure-url="/login.jsp?error=true"
			default-target-url="/loginAction.action" />
        <!-- login-page 登录界面       -->
        <!-- authentication-failure-url 失败返回地址(验证失败,用户名密码错误)       -->
        <!-- default-target-url 成功返回地址 这里我返回到了一个action中,可以进一步操作      -->

		<logout logout-success-url="/login.jsp" />         <!-- 登出跳转地址       -->
<!--	保证一个用户同时只能登入一次
		 <session-management>
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>
-->
	</http>
	
	<!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->
	<authentication-manager alias="authenticationManager">
		<authentication-provider
			user-service-ref="myUserDetailService">
			<!--   如果用户的密码采用加密的
				<password-encoder hash="md5" />
			-->
		</authentication-provider>
	</authentication-manager>
	<beans:bean id="myUserDetailService"
		class="com.yeshun.service.MyUserDetailService" />

</beans:beans>

MyUserDetailService.java   实现用户验证 ,实现UserDetailsService接口

package com.yeshun.service;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.yeshun.util.Md5Util;

public class MyUserDetailService implements UserDetailsService {

	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		
		//这里就不连接数据库了 手动验证用户 及赋予权限
		/**
		 *  UserInfo user = userDao.getUser(username);
		 *  if(user == null){
		 *  	throw new UsernameNotFoundException("用户不存在,请重新输入!");
		 *  }else{
		 *  	// to do 
		 *  	// 根据用户名得到用户的密码 ,得到用户的权限
		 *  }
		 */
		/**
		 * 这里默认密码
		 * 假如配置文件加上了<password-encoder hash="md5" />
		 * String password = Md5Util.MD5("123456"); 
		 */
		String password = "123456";   
		
               //给用户赋予权限,这里就手动了 项目中可以从数据库查出来
		Collection<GrantedAuthority> auths=new ArrayList<GrantedAuthority>();
		GrantedAuthorityImpl auth=new GrantedAuthorityImpl("ROLE_ADMIN");
		auths.add(auth);
//		GrantedAuthorityImpl auth1=new GrantedAuthorityImpl("ROLE_USER");
//		auths.add(auth1);
		boolean enabled = true;
		boolean accountNonExpired = true;
		boolean credentialsNonExpired = true;
		boolean accountNonLocked = true;
//		User(String username, String password, boolean enabled, boolean accountNonExpired,
//        boolean credentialsNonExpired, boolean accountNonLocked, Collection<GrantedAuthority> authorities)
		User user = new User(username,
				password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, auths);
		//假如 数据库是md5加密的 那在配置文件里加上<password-encoder hash="md5" />
		
		return user;
	}

}

UserAction.java    登录成功后返回到这里,可以得到user

package com.yeshun.action;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;


public class UserAction extends BaseAction{

	private static final long serialVersionUID = 1L;

	public String login() {
		//得到登录的用户
		try {
			Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			if (obj instanceof User) {
				User user = ((User) obj);
				String username = user.getUsername();
				String password = user.getPassword();
				List<String> userRoles = new ArrayList<String>();
				Collection<GrantedAuthority> cols =  user.getAuthorities();
				for (GrantedAuthority grantedAuthority : cols) {
					userRoles.add(grantedAuthority.getAuthority());
				}
				// to do some thing ....
				/**
				 * UserInfo userInfo = new UserInfo();
				 * userInfo.setUsername(username);
				 * userInfo.setPassword(password);
				 * userInfo.setRoles(userRoles);
				 * request.getSession().setAttribute("userInfo", userInfo);
				 */
				
				System.out.println("login success.........");
				System.out.println("username:"+username);
				System.out.println("password:"+password);
				for (String str : userRoles) {
					System.out.println("user roles :"+str);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return ERROR;
		}
		return SUCCESS;
	}
}

基本配置文件和java文件都好了,没写的文件里面都就一些标识



下面看登录 login.jsp  (用户名随意的,密码必须是123456  简单识别)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>Spring Security 3</title>
	</head>

	<body>
		<br />
		<center>
			<form name="loginform" action="j_spring_security_check" method="POST" >
				<table align="center" width="600" height="468"
					style="background-image: url();">
					<tr>
						<td height="100">
						</td>
						<td height="100">
						</td>
					</tr>
					<tr>
						<td width="220"></td>
						<td>
							<font size="2"> <span style="color: black"> 用户名</span> <input id="username"
									type='text' name="j_username" value="" style="width: 100px"> <span
								style="color: black">密码</span> <input id="pwd" type='password'
									name='j_password' value="" style="width: 100px"> <input
									name="submit" type="submit" value="登录" class="btn"> </font>
						</td>
					</tr>
				</table>

			</form>
		</center>
	</body>
</html>

主要要记住2点

第一:登录form 的action 必须是 j_spring_security_check

第二:用户名,密码 的name 必须是 j_username,j_password


index.jsp  登录成功后的页面 主要来实现连接的访问权限

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    This is my JSP page. <br>   
    <a href="admin/atestAction.action">admin action</a> <br />
    <a href="welcome.jsp">welcome.jsp</a> <br />
    <a href="user/utestAction.action">user action</a> <br />
    <a href="welcomeUser.jsp">welcomeUser.jsp</a> <br />
    
    <a href="j_spring_security_logout">Logout</a> <br />
  </body>
</html>

这里有一个注意点: 登出的链接必须是 <a href="j_spring_security_logout">


对照项目图,别的jsp内容基本就一些识别标志


附上项目源码点击打开链接


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值