学习的spring boot 2.0的记录(十二):SpringBoot关于security的配置

前言:

学习的地址:https://www.majiaxueyuan.com/front/showcoulist 
SpringBoot的pom依赖(以2.0版本为例的)
本集记录的是security的权限框架  数据库结构和 shiro那节记录的数据库一样的 就不赘述了


目录

1.添加依赖

2.编写application的配置文件

3.编写security的配置类

4.连接数据库查询实现登录

5.测试


 

1.添加依赖

 

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 引入freeMarker的依赖包. -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

 

2.编写application的配置文件

使用的是application.yml类型的

server:
    port: 8080
    tomcat:
        uri-encoding: UTF-8
spring:
    freemarker:
        allow-request-override: false
        cache: true
        charset: UTF-8
        check-template-location: true
        content-type: text/html
        expose-request-attributes: false
        expose-session-attributes: false
        expose-spring-macro-helpers: false
        suffix: .ftl
        template-loader-path: classpath:/templates/
    datasource:
        url: jdbc:mysql://localhost:3306/bootdb?useUnicode=true&characterEncoding=utf-8
        username: root
        password: xxxx
        driver-class-name: com.mysql.jdbc.Driver

前端页面配置:

index:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head lang="en">
    <meta charset="UTF-8"/>
    <title></title>
</head>
<body>
你好啊:${username}
</br>
</br>
</body>
</html>

login页面

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8"/>
    <title></title>
</head>
<body>
骚年 登录 SAO么
${msg}
<form action="/login" method="post">
    <input type="text" name="username"/><br/>
    <input type="password" name="password"/><br/>
    <input type="submit" name="submit"/><br/>
</form>
</body>
</html>

 

3.编写security的配置类

 

主要是处理两个东西:

1.WebSecurityConfig

//注意配置文件 否则会去访问自带的模版
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)  //开启全局安全 就是pre之前 和 post结束之后的
public class WebSecurtiyConfig extends WebSecurityConfigurerAdapter {


    //需要自己创建的DetailUservice
    @Bean
    public MyUserDetailUservice myUserDetailUservice() {
        return new MyUserDetailUservice();
    }

    //配置 AuthenticationManagerBuilder 

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        System.out.println("项目启动执行 第一个 开始走configure auth了!!!!");
        //通过userService去处理
        //后面需要建立一个UserDetailUserService 密码使用的BCryptPasswordEncodeer加盐了的
        auth.userDetailsService(myUserDetailUservice()).passwordEncoder(new BCryptPasswordEncoder());

    }

    //写死的
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

       
    //这个是去处理网站请求的配置

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("项目启动执行 第二个 开始走configure http了!!!!");
        http.csrf().disable();//关闭网站检测
        http.authorizeRequests().anyRequest().fullyAuthenticated();
        //login的方法和表单请求的方法一致 
    
        http.formLogin().loginPage("/login")
        .failureUrl("/errorLogin").defaultSuccessUrl("/index").permitAll();
        http.logout().permitAll();
    }
}

这个配置类是处理http请求以及用户认证的

2.MyUserDetialUserService

这个是用来去数据库查询数据的

@Service
public class MyUserDetailUservice implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleUserMapper roleUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //通过用户名获取用户
        User dbUser = userMapper.getUser(username);
        System.out.println("得到请求后 开始走 MyUserDetailUservice !!!!");
        if (dbUser == null) {
            throw new UsernameNotFoundException("用户查询为空..");
        }
        
        //这个是得到用户角色
        List<Role> roleList = roleUserMapper.getRoleList(username);
        
        //这里是得到角色 然后将放到一个认证的collection当中,然后使用userdetials的用户中    
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Role r : roleList) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_"+r.getRname());
            grantedAuthorities.add(grantedAuthority);
        }
        try {
            org.springframework.security.core.userdetails.User detailUser = new org.springframework.security.core.userdetails.User(username, dbUser.getPassword(), grantedAuthorities);
            return detailUser;
        } catch (Exception e) {
            throw new UsernameNotFoundException("用户密码错误..");
        }
    }
}

可以看到上面需要通过mapper去查询数据过去。所以这里我需要连接数据库

4.连接数据库查询实现登录

首先是需要三个实体类 分别是 用户 角色  和 权限

用户:

@Data
public class User {

    private Integer uid;

    private String name;

    private String password;

    private Integer age;
}

角色:

@Data
public class Role {

    private Integer rid;

    private String rname;

    private String rdescription;

}

权限:

@Data
public class Permission {

    private Integer pid;

    private String pname;

}

接着是创建mapper接口

用户接口

@Mapper
@Repository
public interface UserMapper {

    @Select("SELECT * FROM users WHERE name LIKE #{username} limit 1;")
    User getUser(@Param("username") String username);

    @Insert("INSERT users INTO(name,password,age) VALUES(#{username},#{password},1);")
    void inserUser(@Param("username") String username, @Param("password") String password);

}

角色接口

@Mapper
@Repository
public interface RoleUserMapper {

    @Select("SELECT r.rid, r.rname,r.rdescription FROM users u,role r,role_user ru WHERE u.name =#{userName} and u.uid = ru.uid and ru.rid = r.rid;")
    List<Role> getRoleList(@Param("userName") String userName);

}

权限查询接口

@Mapper
@Repository
public interface RolePermissionMapper {


    @Select("SELECT p.pid,p.pname FROM permission p , permission_role pr ,role r WHERE r.rname = #{roleName} and r.rid =pr.rid and p.pid=pr.pid;")
    List<Permission> getPermissions(@Param("roleName") String roleName);
}

这样所需要的接口和上面的UserDetailService就对上了

然后将使用到的controller写上

登陆用的controller

@Controller
public class loginController{

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/login")
    public String login(Map<String, String> maps) {
        maps.put("msg", "");
        return "login";
    }

    @GetMapping("/errorLogin")
    public String errorLogin(Map<String, String> maps) {
        maps.put("msg", "帐号和密码错误");
        return "login";
    }

}

登陆成功进入的页面

@Controller
public class IndexController {

    @GetMapping("/index")
    public String toIndex(Map<String, Object> maps) {
        //通过上下文获得数据
        SecurityContext context = SecurityContextHolder.getContext();
        //拉取角色数据
        Authentication auth = context.getAuthentication();
        Object userDeatils = auth.getPrincipal();
        System.out.println(userDeatils);
        User securityUser = (User) userDeatils;
        maps.put("username", securityUser.getUsername());
        return "index";
    }
}

在写一个展现角色权限的controller

@RestController
@RequestMapping("/role")
public class RoleController {

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/admin")
    public String getAdmin() {
        return "admin SUCCESS!!!";
    }

    @PreAuthorize("hasRole('ROLE_USER')")
    @GetMapping("/user")
    public String getUser() {
        return "user SUCCESS!!!";
    }

    @PreAuthorize("hasRole('ROLE_SUPERMAN')")
    @GetMapping("/superman")
    public String getSuperMan() {
        return "superman SUCCESS!!!";
    }
}

 

5.测试

通过前台登录看是否能登录到index页面

会跳转到login

因为从

这里看出 他默认是login页面 失败后会跳转到errorLogin请求去,

我们输入一个存在的用户名和密码(这里的密码是加盐了的, 这个加盐方式和md5的不一样)

我们用姬子阿姐的登录试试(密码是123)

说明是成功的。

看后台日志:

得到请求后 开始走 MyUserDetailUservice !!!!
org.springframework.security.core.userdetails.User@2a49a155: Username: 姬子阿姐; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ADMIN,USER

可以看到最后是转成了 security的User类,以及包含了一些常用的参数

是从MyUserdetailUserService中处理的,

得到后 转成了 UserDetail 对象

然后controller通过SecurityContextHolder得到的上下文 拉取到角色对象

这样就展示到前台了。

还有个权限和角色的展示,如下:

有一个rolecontroller

我们去访问 role/admin 可以看到拥有admin权限,

User 权限也有:

但是没有生成superman 的权限

所以前台会报forbidden

这里 springSecurity的一个机制 就是 显示权限必须加上" ROLE_ "的前缀 

可以看到前面在加权限的时候有一个ROLE_+name

是为了在注解   @PreAuthorize("hasRole('ROLE_xxxxx)") 这里使用 这个是 spirng的机制 为了不修改数据库 就在这里加上了一个前缀

记录如上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OAuth2.0是一种常用的认证授权机制,Spring SecuritySpring框架中的安全模块,可以实现OAuth2.0认证。本文将介绍如何利用Spring Boot 2.0Spring Security实现简单的OAuth2.0认证方式1。 1. 添加依赖 在项目的pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.7.RELEASE</version> </dependency> ``` 其中,spring-boot-starter-securitySpring Boot中包含Spring Security的依赖,spring-security-oauth2是Spring Security中实现OAuth2.0的依赖。 2. 配置Spring SecuritySpring Boot应用中,可以通过application.properties或application.yml文件来配置Spring Security。在本文中,我们将使用application.yml文件来配置Spring Security。 ``` spring: security: oauth2: client: registration: custom-client: client-id: custom-client-id client-secret: custom-client-secret authorization-grant-type: authorization_code redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}' scope: - read - write provider: custom-provider: authorization-uri: https://custom-provider.com/oauth2/auth token-uri: https://custom-provider.com/oauth2/token user-info-uri: https://custom-provider.com/userinfo user-name-attribute: sub ``` 其中,我们定义了一个名为custom-client的OAuth2.0客户端,它的客户端ID和客户端密钥分别为custom-client-id和custom-client-secret,授权方式为authorization_code,重定向URI为{baseUrl}/login/oauth2/code/{registrationId},授权范围为read和write。 同时,我们定义了一个名为custom-provider的OAuth2.0提供者,它的授权URI、令牌URI、用户信息URI和用户名属性分别为https://custom-provider.com/oauth2/auth、https://custom-provider.com/oauth2/token、https://custom-provider.com/userinfo和sub。 3. 配置OAuth2.0登录 在Spring Security中,可以通过配置HttpSecurity对象来定义登录、授权等行为。在本文中,我们将使用configure方法来配置HttpSecurity对象。 ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .oauth2Login() .loginPage("/login") .defaultSuccessURL("/dashboard") .and() .logout() .logoutSuccessUrl("/") .permitAll(); } } ``` 其中,我们使用了authorizeRequests方法来设置授权规则,任何请求都需要进行认证,除了根路径和home路径。我们还使用了oauth2Login方法来设置OAuth2.0登录的相关配置,包括登录页面、默认成功URL等。最后,我们使用了logout方法来设置登出的相关配置,包括成功URL等。 4. 配置用户信息 在OAuth2.0认证中,用户信息通常由OAuth2.0提供者来维护。在Spring Security中,可以通过实现UserInfoRestTemplateFactory接口来获取用户信息。 ``` @Configuration public class OAuth2Config { @Bean public OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService() { return new DefaultOAuth2UserService(); } @Bean public UserInfoRestTemplateFactory userInfoRestTemplateFactory() { return new CustomUserInfoRestTemplateFactory(); } } ``` 其中,我们使用了DefaultOAuth2UserService来获取用户信息,同时使用了CustomUserInfoRestTemplateFactory来创建RestTemplate对象。 5. 编写测试 最后,我们可以编写一个简单的测试来验证OAuth2.0认证是否生效。 ``` @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc public class OAuth2Test { @Autowired private MockMvc mockMvc; @Test public void testOAuth2Login() throws Exception { mockMvc.perform(get("/login")) .andExpect(status().isOk()) .andExpect(content().string(containsString("Login with custom-provider"))) .andReturn(); } } ``` 在测试中,我们使用MockMvc对象模拟访问/login路径,期望返回200状态码,并且页面内容中包含“Login with custom-provider”的字符串。 至此,我们已经成功地利用Spring Boot 2.0Spring Security实现了简单的OAuth2.0认证方式1。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值