maven配置spring security5新手简单入门配置

1.pom依赖

第一步肯定是添加引用的包。

<!-- Spring Security-->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>5.0.1.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>5.0.1.RELEASE</version>
    </dependency>
    <!-- Spring Security方法级权限控制注解-->
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>jsr250-api</artifactId>
      <version>1.0</version>
    </dependency>

2.web.xml

第二步肯定是从web启动这个框架。

<!-- SpringSecurity过滤器链 -->
  <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的话,要配置在一块。
其实就是在配置spring的基础上,扫描文件的时候顺便把spring security的xml文件扫描进来就行了。本质就是加一行字的事,很简单

 <!--启动spring容器-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- 指定spring和spring-security配置文件位置 -->
    <param-value>
        classpath:applicationContext.xml  
        classpath:spring-security.xml   
    </param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

3.配置spring-security.xml

简单配置(就是将用户名写死在内存中,不连接数据库,进行一个简单的认证):
登录页面框架已经自带。
我们就规定它要对哪些页面进行安全验证就行了。

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


    <!-- autoconfig使用默认过滤配置   use-expressions是否使用SPEL表达式(没学过) -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置资料连接,表示任意路径都需要ROLE_USER权限 多个权限可以用逗号隔开 -->
        <security:intercept-url pattern="/**" access="ROLE_USER"/>
    </security:http>


    <!-- 相当于不使用数据库读取的密码,在内存中配置用户名和密码还有权限。方便练习 -->
    <!-- {noop}是加密方法的名称,后面跟着是变量名(加密后的内容)。框架规定验证时都需要加密。所以需要这样做-->
 
    <!-- 权限名称以ROLE_开头,之后在数据库存储的也需要这样,不然会报错-->
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="{noop}user"
                               authorities="ROLE_USER" />
                <security:user name="admin" password="{noop}admin"
                               authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

到此为止,最简单的功能已经配置完成啦。能够直接运行项目。正常的话会看到权限不足的提示,然后根据配置的用户名登录就好了。









4.完善配置

有了基础配置,那么接下来配置得更细致一点
不使用Spring Security自带的登录页面,添加自己的登录页面


    <security:http auto-config="true" use-expressions="false" >
        </security:http>

↑这个标签上一步已经写过了
现在要做的是在这个标签加新东西。

  <security:http auto-config="true" use-expressions="false" >
 <!--网页地址-->
        <!--网页表单对应的提交地址-->
        <!--用户名对应表单参数-->
        <!--密码对应表单参数-->
        <!--失败页面-->
        <!--成功页面-->
<security:form-login 
				login-page="/login.html"
			login-processing-url="/login" 	
			username-parameter="username"
			password-parameter="password"
			 authentication-failure-url="/failer.html"
			default-target-url="/success.html" 	/>
			<!-- 登出 删除缓存 -->
		<security:logout invalidate-session="true" logout-url="/logout"
			logout-success-url="/login.jsp" />
		<!-- 关闭CSRF,默认是开启的  防范一种网络攻击方式-->
		<security:csrf disabled="true" />
		        </security:http>

然后自己创建一个页面,填入对应的提交地址,传入对应的用户名和密码,框架会自进行验证。是否和文件里配置的一致。
注意的是需要放行登录页面以及登录失败页面。

 <!-- 配置不过滤的资源(静态资源及登录相关) -->
    <security:http security="none" pattern="/login.html" />
    <security:http security="none" pattern="/failer.html" />
         <!-- 对页面用到的对静态资源文件放行 -->
 <security:http security="none" pattern="/layui-v2.5.5/layui/layui.js" />
<security:http security="none" pattern="/layui-v2.5.5/layui/css/layui.css" />







5.使用数据库的信息进行验证

SpringSecurity提供:

UserDetails接口 用户的信息 (自带,不需要写)
GrantedAuthority接口 权限 (自带,不需要写)
UserDetailsService接口 判断用户

  • 关于UserDetails接口,框架自带一个名叫User的类。我们就不需要动手自己写了。

  • 关于GrantedAuthority接口,框架也带有个叫SimpleGrantedAuthority的类,我们也不需要自己写。当然你想自己动手也行。

框架自带实现UserDetails接口的User类如下:

public class User implements UserDetails, CredentialsContainer {
    private static final long serialVersionUID = 500L;
    private String password;                                //密码
    private final String username; 							//用户名
    private final Set<GrantedAuthority> authorities;	    //权限名称集合 
    private final boolean accountNonExpired;                //是否有效
    private final boolean accountNonLocked;			  	    //是否锁定
    private final boolean credentialsNonExpired;            //认证是否过期
    private final boolean enabled;                          //是否激活

框架自带的实现了GrantedAuthority接口的SimpleGrantedAuthority的类如下:

public final class SimpleGrantedAuthority implements GrantedAuthority {
    private final String role; 								//权限名称

  • 关于UserDetailsService接口,这个接口就只有一个方法。
    实际上就是根据自己的数据库,增删改查,
    查出自己的User属性,再根据对应属性封装成一个框架的User类。
    模板↓
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
	return new User(用户名String,密码String,权限集合Set<GrantedAuthority>);
}

实际上↓

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    TBuserServiceI tBuserService;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        TBuser tBuser = tBuserService.queryOneByUserName(s);
        Set<GrantedAuthority> roleSet = new HashSet();
        for (String role:tBuser.getRoles()
        ) {
            roleSet.add(new SimpleGrantedAuthority(role));
        }
        User user = null;
        if(tBuser!=null){
            user = new User(tBuser.getUsername(),tBuser.getPassword(),roleSet);
            return user;
        }else{
            return null;
        }
    }

代码写好了,就开始配置。记得要在service上标记@Service
接着切换到spring-security.xml 修改先前配置的标签。
因为先前配置,用户名和密码是写死在文件里的,因为现在有数据库了。删掉就行。
在标签里配置属性user-service-ref 对应的UserDetailsService接口实现类
spring-security规定验证用户名和密码时,必须要配置加密类。
加密类就选对应的加密类,这里暂时就选择NoOpPasswordEncoder这个加密类(代表不加密)
配置结果如下:

 <security:authentication-manager>
        <security:authentication-provider user-service-ref="userDetailsServiceImpl">
            <!-- 配置加密的方式 -->
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>
    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder" factory-method="getInstance"/>



6.使用加密类进行信息加密

先前是使用数据库明文存储验证的密码(未加密),现在来改成数据库存储加密后的密码。
spring-security自带了几个加密类。这里使用的是bcrypt加密方式。加密后长度为60位。

在spring-security.xml配置指定的加密类bean
与第5步类似
只是配置加密类从NoOpPasswordEncoder(不加密)换成BCryptPasswordEncoder(bcrypt加密)

 <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

在spring-security.xml配置加密方式。(与第5步一样的配置)

<security:authentication-manager>
        <security:authentication-provider user-service-ref="userDetailsServiceImpl">
            <!-- 配置加密的方式 -->
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>
    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder" factory-method="getInstance"/>

存储用户密码的时候也要使用这个加密类

	@Autowired
    PasswordEncoder passwordEncoder;
    @Override
    public void add(TBuser tBuser) {
        tBuser.setUserid(UUIDUtils.getUUID32());
        tBuser.setPassword(passwordEncoder.encode(tBuser.getPassword()));
        tBuserMapper.insert(tBuser);
    }

存密码的时候,和读取密码的时候,用的都是同一套加密类。所以就能够正常读出来。

数据库中加密前是这样
在这里插入图片描述
数据库中加密后就是这样
在这里插入图片描述







7.方法级别的权限控制

在此之前,先注意一下名称规范。
官方文档这样说,在权限名称前面需要加ROLE_前缀。例如USER要写成ROLE_USER
不然呢xml文件就会解析错误,我试了,是真的。

官方文档 46.3.3 What does “ROLE_” mean and why do I need it on my role names? >https://docs.spring.io/spring-security/site/docs/5.0.6.RELEASE/reference/htmlsingle/#appendix-faq-role-prefix)

所以不仅仅xml配置权限时需要加前缀。最好统一存储的权限名称时也以ROLE_作为前缀。

错误 <security:intercept-url pattern="/**" access="ADMIN,USER"/>
`正确 <security:intercept-url pattern="/**" access=“ROLE_ADMIN,ROLE_USER”/>

统一了权限名称的格式后 就可以开始配置
确认maven是否添加了JSR250依赖。

 <!-- Spring Security方法级权限控制注解-->
    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>jsr250-api</artifactId>
      <version>1.0</version>
    </dependency>

在spring-mvc.xml中配置开启注解权限控制
注意是spring-mvc.xml
注意是spring-mvc.xml
注意是spring-mvc.xml
说三遍!!

 <!--开启jsr-250注解的使用-->
  <security:global-method-security jsr250-annotations="enabled"/>

神坑:如果在spring-security.xml中配置这玩意,就会报错。
我也不知道为什么 ,大概是我配注解在controller上只有springMVC扫描得到??

报错代码500:An Authentication object was not found in the SecurityContext

在需要控制访问权限的方法前,加上权限控制注解。
@RolesAllowed(“ROLE_ADMIN”) 代表含有ROLE_ADMIN角色的用户可以访问。
@RolesAllowed({“ROLE_ADMIN”,“ROLE_USER”}) 代表多个用户可以访问
@PermitAll 代表任何角色可以访问(但是也需要登录)
@DenyAll 拒绝所有角色访问

例如:允许ROLE_ADMIN用户访问goRegister方法。

    @RolesAllowed("ROLE_ADMIN")
    @RequestMapping("goRegister")
    public ModelAndView goRegister(){
        ModelAndView mv = new ModelAndView();

        mv.setViewName("user/register");

        return mv;
    }

配置完毕。再运行项目就会发现,只有ROLE_ADMIN权限的用户可以访问这个方法。
如果想在Controller中获得当前的用户信息怎么办?→可以配置这个Authentication 参数。

authentication代表当前认证对象,可以获得对象信息

@RequestMapping(value = "userInfo",method = RequestMethod.GET )
    public ModelAndView userInfo(TBuser tBuser,Authentication authentication){
        ModelAndView mv = new ModelAndView();
        System.out.println("用户名=="+authentication.getName());
        mv.setViewName("/user/userInfo");
        return mv;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值