SpringSecurity:基本用法

一:创建项目与简单实现

  1. 创建一个spring boot项目,倚赖如下:
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

  1. 创建一个简单的接口如下:
package com.example.springsecurity01.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/19 17:37
 * @Description:
 */
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
        return "Hello";
    }
}

  1. 访问 http://localhost:8080/hello出现登陆界面,用户名默认为user,密码每次随机生成,启动项目时日志当中会有打印,登陆成功后会返回我们想要的结果

  2. 要想自定义用户名和密码我们可以在application.properties中实现

#下面分别为用户名,密码,和用户的角色
spring.security.user.name=root
spring.security.user.password=root
spring.security.user.roles=admin

二:基于内存的认证

package com.example.springsecurity01.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/19 18:00
 * @Description: 基于内存的认证配置了两个用户,继承了WebSecurityConfigurerAdapter
 */
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder(){
   		 //不对密码进行加密
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin").password("123").roles("admin")
                .and()
                .withUser("zhang").password("123").roles("user");
    }

}

三:登陆表单详细配置

以下代码配置了三个用户,不同路径所需要用户的权限,登陆(登出)和及其执行成功后的逻辑处理(本处可返回数据,便于前后端分离开发)

package com.example.springsecurity01.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.*;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
//@EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("root").password("123").roles("ADMIN", "DBA")
                .and()
                .withUser("admin").password("123").roles("ADMIN", "USER")
                .and()
                .withUser("sang").password("123").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //authorizeRequests()方法开启了HttpSecurity配置
        http.authorizeRequests()
                //以下六行配置了访问路径所需要的角色
                .antMatchers("/admin/**")
                .hasRole("ADMIN")
                .antMatchers("/user/**")
                .access("hasAnyRole('ADMIN','USER')")
                .antMatchers("/db/**")
                .access("hasRole('ADMIN') and hasRole('DBA')")
                //下面两行定义了其它url访问必须通过登陆才能访问
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                //登陆界面(自定义的界面)
                //.loginPage("/login_page")
                //登陆处理接口
                .loginProcessingUrl("/login")
                //认证所需的用户名和密码的参数名
                .usernameParameter("name")
                .passwordParameter("passwd")
                //登陆成功的处理逻辑
                .successHandler((req, resp, auth) -> {
                    Object principal = auth.getPrincipal();
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    resp.setStatus(200);
                    Map<String, Object> map = new HashMap<>();
                    map.put("status", 200);
                    map.put("msg", principal);
                    ObjectMapper om = new ObjectMapper();
                    out.write(om.writeValueAsString(map));
                    out.flush();
                    out.close();
                })
//                .successForwardUrl("/hello")
                //登陆失败的处理逻辑
                .failureHandler((req, resp, e) -> {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    resp.setStatus(401);
                    Map<String, Object> map = new HashMap<>();
                    map.put("status", 401);
                    if (e instanceof LockedException) {
                        map.put("msg", "账户被锁定,登录失败!");
                    } else if (e instanceof BadCredentialsException) {
                        map.put("msg", "账户名或密码输入错误,登录失败!");
                    } else if (e instanceof DisabledException) {
                        map.put("msg", "账户被禁用,登录失败!");
                    } else if (e instanceof AccountExpiredException) {
                        map.put("msg", "账户已过期,登录失败!");
                    } else if (e instanceof CredentialsExpiredException) {
                        map.put("msg", "密码已过期,登录失败!");
                    } else {
                        map.put("msg", "登录失败!");
                    }
                    ObjectMapper om = new ObjectMapper();
                    out.write(om.writeValueAsString(map));
                    out.flush();
                    out.close();
                })
                .permitAll()
                //注销登陆配置
                .and()
                //开启注销登陆的配置
                .logout()
                //注销登陆请求的URL
                .logoutUrl("/logout")
                //是否清除个人身份认证信息
                .clearAuthentication(true)
                //是否使session失效
                .invalidateHttpSession(true)
                //可添加注销的操作,如cookie的清除
                .addLogoutHandler((req, resp, auth) -> {

                })
                //注销成功之后的业务逻辑,可添加页面的跳转
                .logoutSuccessHandler((req, resp, auth) -> resp.sendRedirect("/login_page"))
                .and()
                .csrf()
                .disable();
    }
}

添加Controller进行测试

package com.example.springsecurity01.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/19 17:37
 * @Description:
 */
@RestController
public class HelloController {
    @GetMapping("/admin/hello")
    public String admin() {
        return "hello admin!";
    }

    @GetMapping("/admin/db/hello")
    public String admin2() {
        return "/admin/db/hello";
    }

    @GetMapping("/user/hello")
    public String user() {
        return "hello user!";
    }

    @GetMapping("/db/hello")
    public String dba() {
        return "hello dba!";
    }
    
}

四:方法安全

首先要开启基于注解的安全配置

package com.example.springsecurity01.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/20 14:34
 * @Description:
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class WebSecurityConfig {
}

开启后即可在service层进行配置,添加注解后即可对方法的调用进行权限控制

package com.example.springsecurity01.service;

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

/**
 * @Auther: 洺润Star
 * @Date: 2019/9/20 14:40
 * @Description:
 */
@Service
public class MethodService {
    //表示需要ADMIN权限(注意要加前缀ROLE_)
    @Secured("ROLE_ADMIN")
    public String admin() {
        return "hello admin";
    }
    //需要ADMIN和DBA两种权限
    @PreAuthorize("hasRole('ADMIN') and hasRole('DBA')")
    public String dba() {
        return "hello dba";
    }
    //表示需要ADMIN或DBA或USER
    @PreAuthorize("hasAnyRole('ADMIN','DBA','USER')")
    public String user() {
        return "user";
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值