第03讲:Security之用户鉴权

一、创建项目

参考:浅试Security

二、实现用户鉴权

        何为鉴权?说白了其实就是用户认证,用户输入用户名和密码,只有认证通过了才能使用我的系统。
        在实际的项目开发中,账号和密码都是从数据库中查询出来的。所以,我们可以通过自定义逻辑来控制认证。在Security中,如果需要自定义用户认证逻辑(鉴权),只需要实现UserDetailsService接口即可。

2.1、鉴权服务类SecurityService

package demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.authority.AuthorityUtils;
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 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * 自定义鉴权服务类
 */
@Service
public class SecurityService implements UserDetailsService {

    @Autowired
    @Lazy
    private  PasswordEncoder encoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据username,去数据库查该用户的信息
        System.out.println("************");
        System.out.println(username);
        if("tom".equals(username)){
            return new User("tom", encoder.encode("123"), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
        } else {
            throw new UsernameNotFoundException("用户名或密码错误");
        }
    }
}

Tip:实际开发中,我们一般会通过数据库来认证用户信息,大概实现思路是在自定义UserDetailsService类中的loadUserByUsername方法中根据用户名去数据库中查询用户信息,如果满足要求,则用户通过认证,如果不满足要求,则抛出一个UsernameNotFoundException异常,该异常时SpringSecurity内部定义的用于抛出用户不存在的异常。

2.2、Security配置类SecurityConfig

package demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Spring Security配置类
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private SecurityService securityService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(securityService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置没有权限访问时跳转的自定义页面
        http.formLogin() //表单登陆
                .loginPage("/login.html") //登录页面设置
                .loginProcessingUrl("/user/login") //登录访问路径
                .defaultSuccessUrl("/test/index").permitAll(); //登录成功之后跳转路径

        http.authorizeHttpRequests() //认证配置
            .anyRequest() //任何请求
            .authenticated(); //所有请求都拦截

        http.csrf().disable(); //关闭跨站脚本攻击
    }

    /**
     * 将PasswordEncoder注入到ioc容器
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

2.3、自定义登陆页面

如果需要自定义登陆页面,则需要在Security的配置类SecurityConfig中进行配置,如图:
在这里插入图片描述

  • loginPage:设置登陆页面,当前案例登陆页面的位置是/resources/static/login.html
  • loginProcessingUrl:设置登陆访问的路径
  • defaultSuccessUrl:设置从login.html登陆成功之后跳转的路径,如果是从其他url访问,并且通过了认证,是不走这个 defaultSuccessUrl配置的路径的,直接跳转到当前访问的url

/resources/static/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
    <!-- 这里务必注意,用户名和密码对应的name属性值必须是username和password-->
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

/test/index

	@RequestMapping("/test/index")
    public String index(){
        return "欢迎使用xxx管理系统";
    }

2.4、测试

2.4.1、直接访问Controller

访问用于测试的Controller,会进行鉴权

	@RequestMapping("/hello")
    public String hello(){
        return "Hello Spring security";
    }

浏览器输入http://localhost:8080/hello访问Controller,会直接跳转到自定义的登陆页面
在这里插入图片描述
输入正确的用户名(tom)和密码(123),通过认证之后则会将请求转发给刚刚浏览器输入的URL
在这里插入图片描述
如果用户名或者密码输入错误,则不会通过鉴权,重新跳转回自定义的登陆页面

在这里插入图片描述

2.4.2、测试自定义的登陆页面

如果直接访问自定义的登陆页面/resources/static/login.html,如果登陆成功则会将请求转发给预设的URL,当前案例预设的URL是一个Controller(/test/index)
在这里插入图片描述

三、源代码

Security鉴权.zip

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值