SpringScurity的快速入门

什么是SpringScurity

springScurity是为基于spring的应用程序提供安全保护的声明示安全框架,它可以在处理web请求的时候通过过滤器链对类和方法进行认证([authentication)和授权(authorization);

SpringScurity的XML配置

1.导入SpringScurity的相关jar包

2.在web.XML里面配置如下代码:

  <!-- 配置加载类路径的配置文件 -->
 <context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath*:applicationContext.xml,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>

3.创建一个springScurity的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:security="http://www.springframework.org/schema/security"
   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">


<!--配置权限颗粒器-->
<!--@Secured注解支持 : secured-annotations="enabled"-->   
<!--@RolesAllowed注解支持 : jsr250-annotations-->  需要添加jsr250 jar包
<!--开启全局方法安全控制-->
<security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/>

<!--配置不拦截的资源-->
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>


<!--
	配置具体的规则
	auto-config="true"	不用自己编写登录的页面,框架提供默认登录页面
	use-expressions="false"	是否使用SPEL表达式(没学习过)
-->
<security:http use-expressions="true">


    <!--配置具体拦截的url,pattern是拦截的url,access是访问被拦截的url需要的权限-->
    <security:intercept-url pattern="/**" access="hasAnyAuthority('ROLE_USER','ROLE_ADMIN')"/>

    <!--定义跳转的具体页面-->
    <!--
    form-login是spring security命名空间配置登录相关信息的标签,它包含如下属性:
    1. login-page 自定义登录页url,默认为/login
    2. login-processing-url 登录请求拦截的url,也就是form表单提交时指定的action
    3. default-target-url 默认登录成功后跳转的url
    4. always-use-default-target 是否总是使用默认的登录成功后跳转url
    5. authentication-failure-url 登录失败后跳转的url
    6. username-parameter 用户名的请求字段 默认为userName
    7. password-parameter 密码的请求字段 默认为password
    8. authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
    9. authentication-success-forward-url 用于authentication-failure-handler-ref
    10. authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
    11. authentication-failure-forward-url 用于authentication-failure-handler-ref
    12. authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
    -->
    <security:form-login
            login-page="/login.jsp"
            login-processing-url="/login.do"
            default-target-url="/pages/main.jsp"
            always-use-default-target="true"
            authentication-failure-url="/failer.jsp"
    />
    <!--关闭跨域请求,不关闭就会拦截所有的访问,显示权限不够-->
    <!--<security:csrf disabled="true"/>-->
    <security:csrf disabled="true"/>

    <!--退出-->
    <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp"/>

</security:http>


<!--切换成数据库中的用户名和密码-->
<security:authentication-manager>
	<!--配置需要加密的service-->	
    <security:authentication-provider user-service-ref="userService">
        <!-- 配置加密的方式 -->
        <security:password-encoder ref="passwordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>

<!--或者将验证方式改为直接认证不查数据库
 <security:authentication-manager>
	<!--配置service-->
	<security:authentication-provider>	
  		<security:user-service>
  			<security:user username="admin" password="123"  authorities="ROLE_ADMIN"/>
  			<!--如果是springScurity5.0以上的版本
			<security:user username="admin" password="{noop}123"  authorities="ROLE_ADMIN"/>
-->	
  		</security:user-service>
    </security:authentication-provider>
</security:authentication-manager>
这样就不用写用户类和实现类了,账号和密码就是自己在user标签里面配的,权限一定要是<security:intercept-url pattern="/**" access="hasAnyAuthority('ROLE_USER','ROLE_ADMIN')"/>里面的任何一个。也不需要配置加密器了
-->


<!--配置密码加密器,在登陆的时候一定要用密文登陆,如果用明文就需要在密码前加"{noop}"拼接-->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

</beans>

编写service类

1.自定义一个service接口实现UserDetailService(该接口是SpringScurity提供的),复写它的登入方法.原理是当登入页面输入账号密码的时候,过滤器会获取用户在页面输入的数据,然后该接口的实现类会通过用户的账号去查数据库,如果数据库查出的数据和过滤器获取的数据匹配成功,则会跳转到自己设置的认证成功页面在这里插入图片描述,并且该用户拥有相应的权限,就会认证成功,登陆通过。

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.List;

public interface UserService extends UserDetailsService {

@Override
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

2.实现类

import org.springframework.beans.factory.annotation.Autowired;
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.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

//将该类加入spring容器管理
@Service("userService")
//开启注解事务
@Transactional
public class UserServiceImpl implements UserService {

@Autowired
private UserInfoMapper userInfoMapper;

@Autowired
PasswordEncoder passwordEncoder;


@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
	//查询数据库将信息封装到自己的对象类userInfo中
    UserInfo userInfo = userInfoMapper.findUserByUsername(username);
    //获取用户的权限列表
    List<SimpleGrantedAuthority> authority = getAuthority(userInfo.getRoles());
    //User是SpringScurity提供的类
    User user = new User(userInfo.getUsername(),userInfo.getPassword(), userInfo.getStatus() != 0,true,true,true,authority);
    //返回数据之后SpringScurity会将数据库查询的信息与拦截器中的数据对比
    return user;
	}


public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){
    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    for (Role role : roles) {
        authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
    }
   		 return authorities;
	}
}

3.配置完之后,不管访问哪个路径,SpringScurity都会判断该用户是否登陆,如果没有登陆,就会跳转到登陆页面。

猜你喜欢

转载自blog.csdn.net/Bigmuu/article/details/83045840