• spring security learning(spring in action)


    1.使用Spring Security配置命名空间

       spring securtiy 提供了安全性相关的命名空间,我们可以将spring security的命名空间声明添加到spring公用的配置xml文件中,这样在配置安全性的时候我们需要使用security作为前缀来表明配置是关于安全性的配置;同时我们也可以将安全性相关的配置提取出来拆分到一个单独的spring-secutiry.xml文件中,同时将该配置文件的首要命名空间改为安全性命名空间,这样在配置安全性的时候就无需security前缀了。spring-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.xsd
               http://www.springframework.org/schema/security
               http://www.springframework.org/schema/security/spring-security.xsd">
    </beans:beans>

    2.配置对于web请求的保护

      Spring Security 借助一系列的Servlet过滤器来提供各种安全功能,需要在web.xml里加入一个过滤器:

    <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>

      DelegatingFilterProxy将工作委托给一个javax.servlet.filter实现类,这个实现类作为一个bean注册在Spring应用的上下文中。在这里我配置的过滤器将过滤所有的web请求。

      接下来就可以配置安全性了,在这里使用<http>元素进行配置,<http>会自动创建一个FilterChainProxy以及链中的所有过滤器Bean,FilterChainProxy将会委托给在web.xml中的delegatingFilterProxy。同时<http>还有一个auto-config属性,如果设为true,即采用spring security的自动配置,它将会为我们提供一个登陆页、http认证功能以及退出功能。

     <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    
     <intercept-url pattern="/user/register.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>

      在这里我首先采用 <http pattern="/resources/**" security="none"></http> 让spring security 对于所有resources下的请求都不进行安全性认证,因为resources下是系统的一些图片、css、js资源。

      其次对于登陆页面和注册页面的请求,也不进行安全性认证(IS_AUTHENTICATED_ANONYMOUSLY:即匿名身份验证):

       

      然后对登录页面进行设置:

       

     <form-login login-processing-url="/user/login.html" login-page="/login.jsp" default-target-url="/user/index.html"
              authentication-failure-url="/login.jsp" />

          login-processing-url:登录请求

          login-page:登录页面

          default-target-url:登录成功以后默认跳转到的页面

          default-target-url:认证失败后跳转到的页面

      登录页面设置完毕后对退出系统进行设置:

       

     <logout logout-success-url="/login.jsp" logout-url="/user/logout.html"/>

          logout-success-url:退出成功以后跳转的页面

          logout-url:退出的请求

    完整的web认证配置:

    <http pattern="/resources/**" security="none"></http>
    
            <http>
                <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
                <intercept-url pattern="/register.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
                <intercept-url pattern="/**" access="ROLE_ADMIN"/>//所有的请求都要有ROLE_ADMIN的权限才能访问
                <form-login login-processing-url="/user/login.html" login-page="/login.jsp" default-target-url="/user/index.html"
                            authentication-failure-url="/login.jsp" />
                            
                <logout logout-success-url="/login.jsp" logout-url="/user/logout.html"/>
            </http>   

    3.对用户进行认证

      spring security 有多种对于用户的策略,基于内存用户存储库,基于jdbc的用户存储库,基于LDAP的用户存储库等等,在这里我选用的是基于jdbc即基于数据库的认证。

      首先实现UserDetailsService接口,实现类叫myUserDetailsService,并在spring-security中声明这个bean

     <logout logout-success-url="/login.jsp" logout-url="/user/logout.html"/>

    myUserDetailsService:

    @Service
    public class MyUserDetailsService implements UserDetailsService{
        
        private static Logger log = Logger.getLogger(MyUserDetailsService.class);
    
        @Autowired
        private UserDao userDao;
        public UserDetails loadUserByUsername(String username)
                throws UsernameNotFoundException {
            User user = new User();
            try{
                user =  userDao.getByColumn("username",username);
            }catch(Exception e){
                e.printStackTrace();
                log.error("spring security load user fail", e.getCause());
            }
            return user;
        }
        
    }

    通过这个service从数据库获取User对象,但是要注意UserDetailsService接口中的loadUserByUsername()方法返回的是UserDetails对象,所以你的User对象必须继承自UserDetails接口,并且实现接口中的方法。

    User:

    public class User implements UserDetails{    
       private Integer user_id; private String username; private String password; private List<Role> roles; public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public Collection<? extends GrantedAuthority> getAuthorities() {//获取认证的权限 List<GrantedAuthority> list = new ArrayList<GrantedAuthority>(); for(Role role : roles){ GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getAuthority()); list.add(grantedAuthority); } return list; } //用户是否未过期 public boolean isAccountNonExpired() { return true; } //用户是否被锁定 public boolean isAccountNonLocked() { return true; } //凭据是否过期 public boolean isCredentialsNonExpired() { return true; } //用户是否可用 public boolean isEnabled() { return true; } }

    权限类:

      

    public class Role {
        private String username;
        private String authority;
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getAuthority() {
            return authority;
        }
        public void setAuthority(String authority) {
            this.authority = authority;
        }
    }
     

    声明了myUserDetailsService以后,就可以使用myUserDetailsService作为认证的提供者了:

     <authentication-manager>
                <authentication-provider user-service-ref="myUserDetailsService">
                    <password-encoder ref="passwordEncoder">
                        <salt-source user-property="username"/>
                    </password-encoder>
                </authentication-provider>
            </authentication-manager>

    在这里我们必须将密码使用的加密方式进行声明,否则service不会对用户输入的密码进行加密,那么数据库和用户输入的密码就不可能对上。这儿我使用的加密的方式是md5加密,使用的盐值是用户的用户名。

    加密bean的声明:

    <beans:bean id="passwordEncoder"
              class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />

    基本的配置已经完成了,最后需要注意的一点就是在写用户登录表单的时候,用户名和密码的name注意是:j_username和j_password,否则将会取不到用户输入的用户名和密码的值。

    到这里一个简单的spring security的配置就基本完成了。当然spring security的安全性功能远远还不止这些,等待继续深一步的学习。  

  • 相关阅读:
    Unity3d for beginners
    iOS 8 swift 键盘不出来 ios 8 uitextfield keyboard not appearing
    关于Cookie跨域的问题
    45种Javascript技巧大全
    新.Net架构必备工具列表
    .NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱
    ASP.NET 大文件下载的实现思路及代码
    理解 .NET 2015
    转:我是否该放弃VB.Net?
    .net中的一般处理程序实例
  • 原文地址:https://www.cnblogs.com/sirhuoshan/p/3574175.html
Copyright © 2020-2023  润新知