黑马程序员技术交流社区

标题: 【广州校区】 spring-security高级体验 [打印本页]

作者: Mylo    时间: 2019-1-10 14:42
标题: 【广州校区】 spring-security高级体验
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.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/s ... spring-security.xsd">

    <security:http auto-config="true" use-expressions="false">
    <!--    <security:intercept-url pattern="/welcome**" access="ROLE_USER"></security:intercept-url>
        <security:intercept-url pattern="/admin**" access="ROLE_ADMIN"></security:intercept-url>
-->
    <security:form-login login-page="/pages/login.jsp" authentication-failure-url="/pages/error.jsp"></security:form-login>
    <security:logout logout-success-url="/pages/login.jsp"></security:logout>
    <security:csrf disabled="true"></security:csrf>
        <security:custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"></security:custom-filter>
    </security:http>


   
    <security:authentication-manager id="authenticationManager">
        <security:authentication-provider user-service-ref="myUserDetailsService">
        <!--    <security:user-service>
                <security:user name="mylo" password="{noop}123456" authorities="ROLE_USER"></security:user>
                <security:user name="admin" password="{noop}123456" authorities="ROLE_ADMIN"></security:user>
            </security:user-service>-->
        </security:authentication-provider>
        
    </security:authentication-manager>

    <bean class="cn.test.service.MyUserDetailsService" id="myUserDetailsService"> </bean>


    <bean class="cn.test.auth.MyFilter" id="myFilter">
        <property name="accessDecisionManager"  ref="accessDecisionManager"></property>
        <property name="authenticationManager" ref="authenticationManager"></property>
        <property name="securityMetadataSource" ref="mySecurityMetadataSource"></property>
    </bean>
    <bean class="cn.test.auth.MyAccessDecisionManager" id="accessDecisionManager"></bean>
    <bean class="cn.test.auth.MySecurityMetadataSource" id="mySecurityMetadataSource"></bean>
</beans>

web.xml
<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">

    <display-name>spring security</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-security.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
   
    <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>

    <servlet>
        <servlet-name>sprinmvcDispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>sprinmvcDispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>


springmvc.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       ">

    <context:component-scan base-package="cn.test.controller" />


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="suffix" value=".jsp" ></property>
        <property name="prefix" value="/pages/"></property>
    </bean>
    <mvc:annotation-driven></mvc:annotation-driven>
    <mvc:default-servlet-handler></mvc:default-servlet-handler>



</beans>
MyUserDetailsServicepackage cn.test.service;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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 java.util.ArrayList;
import java.util.List;

/**
* @program: test4Security
* @description: test4springSecurity
* @author: Mylo
* @create: 2019-01-04 10:06
*
* 验证
**/
public class MyUserDetailsService implements UserDetailsService {
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //模拟赋值权限

        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();




        //模拟从数据库获取信息  校验
        if("mylo".equals(s)){

            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new User(s,"{noop}123456",authorities);
        }

        if("admin".equals(s)){
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            return new User(s,"{noop}123456",authorities);
        }



        return null;
    }
}


controller
package cn.test.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
* @program: test4Security
* @description: test4security
* @author: Mylo
* @create: 2019-01-04 09:44
**/

@Controller
public class LoginController {

    @RequestMapping("common")
    public String common(){

        return "common";
    }

    @RequestMapping("admin")
    public String admin(){

        return "admin";
    }

    @RequestMapping("welcome")
    public String welcome(){

        return "welcome";
    }


}

package cn.test.auth;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
* @program: test4Security
* @description:
* @author: Mylo
* @create: 2019-01-04 10:33
*
*  定义 地址访问所需要的权限
**/
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    private Map<String , Collection<ConfigAttribute>> map = new HashMap<String ,Collection<ConfigAttribute>>();


    //o 请求的地址
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        Collection<ConfigAttribute> c1 = new ArrayList<ConfigAttribute>();
        Collection<ConfigAttribute> c2= new ArrayList<ConfigAttribute>();
        ConfigAttribute s1 = new SecurityConfig("ROLE_USER");
        ConfigAttribute s2 = new SecurityConfig("ROLE_ADMIN");
        c1.add(s1);
        c2.add(s2);

        map.put("/welcome**" , c1);
        map.put("/admin**" , c2);

        String url = ((FilterInvocation) o).getRequestUrl();
        if(url.contains("welcome")){
              return map.get("/welcome**");
        }

        if(url.contains("admin")){
            return map.get("/admin**");
        }

        return null;
    }

    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    public boolean supports(Class<?> aClass) {
        return true;
    }
}




package cn.test.auth;


import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;

import javax.servlet.*;
import java.io.IOException;

/**
* @program: test4Security
* @description: test
* @author: Mylo
* @create: 2019-01-04 10:16
*
* 校验 权限
**/
public class MyFilter extends AbstractSecurityInterceptor implements Filter {

    /**
     *
     */
    private FilterInvocationSecurityMetadataSource securityMetadataSource;

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //封装request response chain
        FilterInvocation filterInvocation = new FilterInvocation(request,response,chain);
        InterceptorStatusToken token = super.beforeInvocation(filterInvocation);

        try {
            filterInvocation.getChain().doFilter(filterInvocation.getRequest(),filterInvocation.getResponse());
        }finally {
            super.afterInvocation(token,null);
        }

    }

    public void destroy() {

    }

    public Class<?> getSecureObjectClass() {
        return FilterInvocation.class;
    }

    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }


    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return securityMetadataSource;
    }

    public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
        this.securityMetadataSource = securityMetadataSource;
    }
}



package cn.test.auth;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;
import java.util.Iterator;

/**
* @program: test4Security
* @description:
* @author: Mylo
* @create: 2019-01-04 10:42
*
* 判断当前用于的权限 以及 访问当前路径所需要的权限
**/
public class MyAccessDecisionManager implements AccessDecisionManager {
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        Iterator<ConfigAttribute> iterator = collection.iterator();
        while(iterator.hasNext()){
            ConfigAttribute attribute = iterator.next();
            //访问所需要的权限
            String attr = attribute.getAttribute();
            //当前用户所拥有的权限
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                if(authority.getAuthority().equals(attr)){
                    return ;
                }
            }
        }
        throw new AccessDeniedException("没有权限访问");

    }

    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    public boolean supports(Class<?> aClass) {
        return true;
    }
}






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2