学习spring-Security3.0

来源:互联网 发布:指纹定位算法 编辑:程序博客网 时间:2024/05/22 19:26

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-provideruser-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"> <spanstyle="color: black">密码</span> <input id="pwd" type='password'name='j_password' value="" style="width: 100px"> <inputname="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内容基本就一些识别标志


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


原创粉丝点击