1 Star 0 Fork 0

MZQ / exp4

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

     东莞理工学院网络空间安全学院实验报告

课程名称:企业级开发框架专题                      学期:2020年春季

实验名称:基于Spring Security码云OAuth2认证                实验序号:四

姓名:麦子全             学号:201741412223        班级:17软件1班

实验日期:2020-5-14            实验类型:综合          指导老师:黎志雄

一、实验目标:

  1. 掌握使用Spring Security框架;
  2. 掌握配置Spring Security的安全过滤链;
  3. 掌握编写Spring Security单元测试;
  4. 掌握创建接入码云的应用;
  5. 掌握码云OAuth2认证基本流程;
  6. 掌握使用码云API;
  7. 了解使用模板引擎或前端框架制作用户登录界面.

二、实验条件:

  1. JDK 1.8或更高版本
  2. Maven 3.6+
  3. IntelliJ IDEA

三、实验内容及结果分析:

  1. 登录码云,fork实验四的作业仓库:
  1. 根据下面的步骤填充代码,运行并测试成功:
    (1)创建接入码云的应用:

获取CLIENT_ID和CLIENT_SECRET:

static final String CLIENT_ID = "0a0e670f4ac34bf8c77711a61e13520a151e5188511350f211829bcb578756fc";
static final String CLIENT_SECRET = "980a02c97074b79f157bae9193cd01f1cf89ff689425cc993da4120240612fb5";

(2)编写重定向过滤器的业务逻辑: 当用户访问/oauth2/gitee时,本重定向过滤器拦截请求,并将用户重定向到码云三方认证页面上

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            // 如果不是/oauth2/gitee请求,则继续下一个过滤器。
            if (!request.getRequestURI().endsWith(DEFAULT_AUTHORIZATION_REQUEST_BASE_URI)) {
                filterChain.doFilter(request, response);
                return;// 执行完安全过滤器链后不执行后面的代码。
            }
            /// 步骤二:编写重定向过滤器的业务逻辑。
            String redirectUrl = UriComponentsBuilder.fromUriString("https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code")
                    .encode()
                    .buildAndExpand(CLIENT_ID,REDIRECT_URI)
                    .toUriString();
            redirectUrl = response.encodeRedirectURL(redirectUrl);
            response.sendRedirect(redirectUrl);
}

(3)使用码云access_token API向码云认证服务器发送post请求获取access_token:

private String getAccessToken(String code) {
            /// 步骤三:使用码云access_token API向码云认证服务器发送post请求获取access_token。
           URI accessUrl = UriComponentsBuilder.fromHttpUrl(ACCESS_TOKEN_API_URI)
                   .encode()
                   .buildAndExpand(code,CLIENT_ID,REDIRECT_URI,CLIENT_SECRET)
                   .toUri();

            RequestEntity<Void> requestEntity = RequestEntity
                    .post(accessUrl)
                    .header("User-agent","Chrome")
                    .build();

           String result = rest.exchange(requestEntity,String.class).getBody();
           Map<String,Object> stringObjectMap = new JacksonJsonParser().parseMap(result);
           return (String)stringObjectMap.get("access_token");
}

(4)使用码云API获取授权用户的资料:

private Map<String, Object> getUserInfo(String accessToken) {
           /// 步骤四:使用码云API获取授权用户的资料。
    URI userUrl=UriComponentsBuilder.fromHttpUrl(USER_INFO_URI)
            .encode()
            .buildAndExpand(accessToken)
            .toUri();
    RequestEntity<Void> requestEntity = RequestEntity
            .get(userUrl)
            .header("User-agent","Chrome")
            .build();

    String result=rest.exchange(requestEntity,String.class).getBody();
    JacksonJsonParser jacksonJsonParser=new JacksonJsonParser();
    return jacksonJsonParser.parseMap(result);
}

(5)把自定义的两个Filter加进安全过滤链:

public void configure(H http) {
     /// 步骤五:把自定义的两个Filter加进安全过滤链
     http.addFilterAfter(new GiteeOAuth2RedirectFilter(), SecurityContextPersistenceFilter.class);
     http.addFilterAfter(new GiteeOAuth2LoginAuthenticationFilter(), SecurityContextPersistenceFilter.class);
}

(6)把我们自定义的SecurityConfigurer应用到安全过滤链:

protected void configure(HttpSecurity http) throws Exception {
    // 不指定path,本安全过滤链会匹配所有请求。
    http
            .authorizeRequests()
            .antMatchers("/").permitAll()// 首页放行
            .anyRequest().hasAnyAuthority("USER").and()
            .formLogin()
            .loginPage("/user/login_frontend").permitAll()
            .defaultSuccessUrl("/user").and()
            .logout()
            .logoutUrl("/user/logout").permitAll()
            .logoutSuccessUrl("/user/login_frontend?logout").and()
            // 自定义访问拒绝异常处理逻辑
            .exceptionHandling().accessDeniedHandler(UserSecurityConfig::accessDeniedHandle)
            /// 步骤六:把我们自定义的SecurityConfigurer应用到安全过滤链
            .and()
            .apply(giteeOAuth2LoginConfigurer);
}

(7)改造/user接口,返回码云用户资料给前端;改造user.ftlh模板用于显示用户资料:

@GetMapping("/user")
public String userIndex(Model model) {
    /// 步骤七:改造/user接口,返回码云用户资料给前端;改造user.ftlh模板用于显示用户资料。
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    UserDetails userDetail = (UserDetails) authentication.getPrincipal();
    model.addAttribute("userDetails",userDetail);
    return "user";
}

(8)编写单元测试。模拟一个登录用户,访问受保护的接口/test,断言接口的返回内容body部分是否一致:

@Test
    @WithMockUser(username = "user",authorities = {"USER"})
public void test() throws Exception {
    /// 步骤八:模拟一个登录用户,访问受保护的接口/test,断言接口的返回内容body部分是否一致。
    mvc.perform(get("/test").header("User-Agent","Chrome"))
            .andExpect(status().isOk())
            .andExpect(content().string("欢迎您"));
}

四、实验总结

通过此次实验,我了解如何使用Spring Security框架、配置Spring Security的安全过滤链、编写Spring Security单元测试、创建接入码云的应用、码云OAuth2认证基本流程、使用码云API、了解使用模板引擎或前端框架制作用户登录界面,初步了解这些知识,以后的学习中不断深入学习和掌握。

空文件

简介

基于Spring Security码云OAuth2认证 展开 收起
Java
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/maiziq/exp4.git
git@gitee.com:maiziq/exp4.git
maiziq
exp4
exp4
master

搜索帮助