spring security 使用笔记

来源:互联网 发布:手机经纬度导航软件 编辑:程序博客网 时间:2024/04/29 03:11

首先是web.xml文件,将spring security 监听配置进去。

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="payPluginMgr" version="3.0">    <display-name>ssecurity</display-name>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>            classpath*:/config/applicationContext.xml,classpath*:/config/dao.xml,classpath*:/config/service.xml,classpath*:/config/spring-security.xml,        </param-value>    </context-param>    <context-param>        <param-name>log4jConfigLocation</param-name>        <param-value>classpath:log4j.properties</param-value>    </context-param>    <!--配置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>    <!--配置spring mvc-->    <servlet>        <servlet-name>ssecurity</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>ssecurity</servlet-name>        <url-pattern>*.do</url-pattern>    </servlet-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>


spring-security.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:security="http://www.springframework.org/schema/security"       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.2.xsd">    <!--  Spring-Security 的配置 -->    <security:http use-expressions="true" auto-config="true" access-denied-page="/403.jsp">        <!--permitAll所有请求都返回TRUE-->        <security:intercept-url pattern="/user/login.do" access="permitAll"/>        <!--Role_0角色 可以访问admin.co-->        <security:intercept-url pattern="/user/admin.do" access="hasRole('ROLE_0')"/>        <!--login-page,登陆页面,default-target-url 成功后跳转页面,login-processing-url 登陆处理-->        <!--always-use-default-target 登陆成功后一直跳转,username-parameter login传入的username、password-->        <!--authentication-success-handler-ref 登陆成功后处理-->        <security:form-login                login-page="/user/login.do"                default-target-url="/user/index.do" login-processing-url="/user/admin.do"                always-use-default-target="true" username-parameter="username" password-parameter="password" authentication-success-handler-ref="authenticationSuccessHandler"  />        <security:logout                invalidate-session="true"                logout-success-url="/auth/login"                logout-url="/auth/logout"/>        <!--登陆后记住-->        <security:remember-me />    </security:http>    <!--登陆成功处理bean,用这个的时候,default-target-url将失效,所以这里要再次注明登陆后的跳转-->    <bean id="authenticationSuccessHandler" class="com.security.security.listener.AuthenticationSuccessService">        <property name="defaultTargetUrl" value="/user/index.do"></property>        <property name="forwardToDestination" value="false"></property>    </bean>     <!--指定一个自定义的authentication-manager :customUserDetailsService-->    <security:authentication-manager>        <!--注入authenticationProvider-->        <security:authentication-provider ref="authenticationProvider">        </security:authentication-provider>    </security:authentication-manager>    <bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">        <!--注入UserDetailsServiceImpl-->        <property name="userDetailsService" ref="customUserDetailsService" />        <!--这里没有对密码加密,如果需要加密在这里添加,支持MD5、明文和哈希-->    </bean>    <!--这个Service用来匹配用户账号、密码以及权限等信息-->    <bean id="customUserDetailsService" class="com.security.security.service.impl.UserDetailsServiceImpl">    </bean></beans>

UserDetailsImpl.java 

这个类实现UserDetails接口,主要是将数据库中保存的用户数据封装成security用到的数据,比如将用户名、密码、用户状态等信息封装

package com.security.security.service.impl;import com.security.model.Role;import com.security.model.TUser;import com.security.security.model.UserDetailsImpl;import com.security.service.UserService;import org.springframework.context.support.MessageSourceAccessor;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.SpringSecurityMessageSource;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import javax.annotation.Resource;import java.util.*;public class UserDetailsServiceImpl implements UserDetailsService {    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();    @Resource(name = "userService")    private UserService userService;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        Map<String,String> map = new HashMap<String, String>();        map.put("username",username);        TUser tUser = userService.selectById(map);        if(null == tUser){            throw new UsernameNotFoundException(messages.getMessage("User not found", new Object[]{username}, "Username {0} not found"));        }        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();        List<Role> tRoles = new ArrayList<Role>();        Role role = new Role();        role.setId(0);        tRoles.add(role);        for (Role tRole : tRoles){            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + tRole.getId());            authorities.add(authority);        }        UserDetailsImpl tUserDetailsImpl = new UserDetailsImpl(tUser, authorities);        return tUserDetailsImpl;    }}

UserDetailsServiceImpl.java

这个类是从数据库中取用户信息、权限,然后调用上面的UserDetailsImpl,将数据封装起来。在spring-security.xml中我们将这个Service注入给了authenticationProvider。

package com.security.security.service.impl;import com.security.model.Role;import com.security.model.TUser;import com.security.security.model.UserDetailsImpl;import com.security.service.UserService;import org.springframework.context.support.MessageSourceAccessor;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.SpringSecurityMessageSource;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import javax.annotation.Resource;import java.util.*;public class UserDetailsServiceImpl implements UserDetailsService {    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();    @Resource(name = "userService")    private UserService userService;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        Map<String,String> map = new HashMap<String, String>();        map.put("username",username);//        根据username从数据库中匹配用户信息        TUser tUser = userService.selectById(map);        if(null == tUser){            throw new UsernameNotFoundException(messages.getMessage("User not found", new Object[]{username}, "Username {0} not found"));        }//        封装用户角色        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();//        从数据库中读取用户角色。我这边没用真从数据库中读取,mock了一个tRoleslist        List<Role> tRoles = new ArrayList<Role>();        Role role = new Role();        role.setId(0);        tRoles.add(role);        for (Role tRole : tRoles){            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + tRole.getId());            authorities.add(authority);        }//        调用tUserDetailsImpl 封装user信息和权限        UserDetailsImpl tUserDetailsImpl = new UserDetailsImpl(tUser, authorities);        return tUserDetailsImpl;    }}
AuthenticationSuccessService.java ,这个是一个成功后调用的方法,注意forwardToDestination和defaultTargetUrl。

package com.security.security.listener;import com.security.model.TUser;import com.security.security.model.UserDetailsImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.Authentication;import org.springframework.security.web.DefaultRedirectStrategy;import org.springframework.security.web.RedirectStrategy;import org.springframework.security.web.authentication.AuthenticationSuccessHandler;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class AuthenticationSuccessService implements AuthenticationSuccessHandler {        private String defaultTargetUrl;        private boolean forwardToDestination = false;        private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();    /* (non-Javadoc)     * @see org.springframework.security.web.authentication.AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.Authentication)     */        @Override        @Transactional(readOnly=false,propagation= Propagation.REQUIRED,rollbackFor={Exception.class})        public void onAuthenticationSuccess(HttpServletRequest request,                HttpServletResponse response, Authentication authentication)        throws IOException, ServletException {            this.saveLoginInfo(request, authentication);            if(this.forwardToDestination){                request.getRequestDispatcher(this.defaultTargetUrl).forward(request, response);            }else{                this.redirectStrategy.sendRedirect(request, response, this.defaultTargetUrl);            }        }        @Transactional(readOnly=false,propagation= Propagation.REQUIRED,rollbackFor={Exception.class})        public void saveLoginInfo(HttpServletRequest request,Authentication authentication){            UserDetailsImpl user = (UserDetailsImpl)authentication.getPrincipal();            String ip = this.getIpAddress(request);            System.out.println(ip);        }    public String getIpAddress(HttpServletRequest request){        String ip = request.getHeader("x-forwarded-for");        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("WL-Proxy-Client-IP");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("HTTP_CLIENT_IP");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("HTTP_X_FORWARDED_FOR");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getRemoteAddr();        }        return ip;    }    public void setDefaultTargetUrl(String defaultTargetUrl) {        this.defaultTargetUrl = defaultTargetUrl;    }    public void setForwardToDestination(boolean forwardToDestination) {        this.forwardToDestination = forwardToDestination;    }}

如此便配置完成了。

总结:
1,web.xml中添加spring-security监听

2,配置spring-security相关参数

3,查询用户的信息及权限,封装成security需要的数据

4,登陆成功后自定义处理事件(有特殊需求事)。


第一次写博客,如果有不正确不恰当 的地方,请朋友们指出- -


0 0