【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio构建SpringSecurity权限框架

1.Cloud Studio(云端 IDE)简介

Cloud Studio 是基于浏览器的集成式开发环境(IDE),为开发者提供了一个永不间断的云端工作站。用户在使用 Cloud Studio 时无需安装,随时随地打开浏览器就能在线编程。

Cloud Studio 作为在线 IDE,包含代码高亮、自动补全、Git 集成、终端等 IDE 的基础功能,同时支持实时调试、插件扩展等,可以帮助开发者快速完成各种应用的开发、编译与部署工作。

云端 IDE(Web IDE/在线 IDE/Cloud IDE)作为托管在云中的服务运行,不再只是云端的软件开发环境,而是提供了包括基础设施服务的 Development-environment-as-a-Service 的服务模式,其天然具有如下优势:

  • 无需在本地维护和设置项目;
  • 更好的共享和协作;
  • 直接集成/访问云服务;
  • 改进上下文切换(不同的项目、分支等)的方式和效率;
  • 源代码的集中控制和保密;

随着云计算技术的成熟和普及,越来越多的传统编程能力和资源以云服务的形式开放出来,从中间件、数据库等水平能力服务组件到人脸识别、鉴权服务等基本业务服务组件都可以很容易的在云端获取。一旦世界从基于 IaaS 的应用开发转变为基于 IaaS、PaaS 甚至 SaaS 的混合应用开发模式,云端 IDE(Web IDE/在线 IDE/Cloud IDE)将成为连接开发人员、PaaS、SaaS 云服务所有服务组件的最佳选择。

Cloud Studio提供了大量常用语言模板,无论您是前端、后端、算法、全栈开发者,在Cloud Studio都能找到符合您的那一款。

同时,Cloud Studio还提供了数十种模板应用,包括AI聊天、俄罗斯方块、语言翻译等。真正做到多款应用开箱即用,Cloud Studio也提供了丰富的应用生态,开发者可以随时提交自己的good idea。

2.应用场景

Cloud Studio 在线编程工具适用于以下几个场景:

2.1 快速启动项目

使用 Cloud Studio 的预置环境,您可以直接创建对应类型的工作空间,快速启动项目进入开发状态,无需进行繁琐的环境配置。

2.2 实时调试网页

Cloud Studio 内置预览插件,可以实时显示网页应用。当您的代码发生改变之后,预览窗口会自动刷新,这样您就可以在 Cloud Studio 内实时开发调试网页了。

2.3 远程访问云服务器

Cloud Studio 支持您连接自己的云服务器,这样就可以在编辑器中查看云服务器上的文件,进行在线编程和部署工作。

2.4 协助开发

在居家办公场景下,遇到难以解决的问题可以协调其他同组人员一起刨析和解决问题。

2.5 开发流程

提供沟通、编排、排错、评审、测试一系列开发流程,使用者只需要关注业务开发即可。

2.6 强大的devops生态

配合git平台coding+腾讯云服务器+Cloud Studio,中小企业轻松落地devops生态,低成本上云、

3.SpringSecurity简介

Spring Security是基于Spring 的身份认证(Authentication)和用户授权(Authorization)框架,提供了一套 Web 应用安全性的完整解决方案。是市面上企业级安全框架的最优选择。

身份认证指的是用户去访问系统资源时,系统要求验证用户的身份信息,用户身份合法才访问对应资源。常见的身份认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。

当身份认证通过后,去访问系统的资源,系统会判断用户是否拥有访问该资源的权限,只允许访问有权限的系统资源,没有权限的资源将无法访问,这个过程叫用户授权。比如 会员管理模块有增删改查功能,有的用户只能进行查询,而有的用户可以进行修改、删除。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

通俗的说,SpringSecurity提供了账号密码的校验和操作人是否有权限访问接口的功能。

4 快速开始项目

这里使用Cloud Studio快速开始一个SpringSecurity项目。

4.1 新建命名空间

这里提供了两种方式:

  1. 可以新建空的工作空间,按照博文完成项目构建。
  2. 也可以通过coding导入项目,项目地址:https://e.coding.net/bcl3/spring/CloudStudioSecurity.git

代码结构如下:

4.2 新建实体类

这里提供通用的返回方法与项目实体类。

由于篇幅原因,这里不提供get/set方法,需要源代码请使用coding下载。

4.2.1 Authentication

该类获取Application.yml中提供的常量。

代码语言:java
复制
@ConfigurationProperties(prefix = "authentication")

@Component

public class Authentication {

private String loginPage;

private String loginProcessingUrl;

private String username;

private String password;

private String[] staticPaths ;</code></pre></div></div><h4 id="9b8k4" name="4.2.2-Result">4.2.2 Result</h4><p>用于提供统一返回格式。</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>java</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-java"><code class="language-java" style="margin-left:0">public class Result {



private Integer code;



private String message;



private Object data;</code></pre></div></div><h3 id="5ccpj" name="4.3-Service">4.3 Service</h3><p>UserService类查询账号密码,验证账号密码是否正确,这里不连接数据库,只提供模拟查询验证,各位可再基础上自行拓展。</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>java</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-java"><code class="language-java" style="margin-left:0">@Component(&#34;userService&#34;)

public class UserService implements UserDetailsService {

Logger logger = LoggerFactory.getLogger(getClass());


@Autowired

PasswordEncoder passwordEncoder;



@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

    logger.info(&#34;输入的账号: &#34; + username);

    if(!&#34;CloudStudio&#34;.equalsIgnoreCase(username)) {

        throw new UsernameNotFoundException(&#34;用户名或密码错误&#34;);

    }

    String password = passwordEncoder.encode(&#34;1234&#34;);

    //模拟返回权限

    return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList(&#34;admin&#34;));

}

}

4.4 SpringSecurityConfig(核心)

该类为SpringSecurity的核心类:

  1. configure(AuthenticationManagerBuilder auth):方法用于指定验证账号密码的方法。也就是调用上文的UserService。
  2. configure(WebSecurity web):用于放行静态资源,静态资源可以不用验证账号。
  3. configure(HttpSecurity http):用于配置什么接口验证账号,什么接口可以匿名访问,同时可以指定自定义过滤器,这里指定了AuthenticationSuccessHandler /AuthenticationFailureHandler,用于验证成功/失败的处理。同时在此处,还可以添加验证码过滤器,token过滤器器等,扩展知识可以参考博主SpringSecurity/Oauth专栏。
代码语言:java
复制
@Configuration

@EnableWebSecurity

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

UserDetailsService userDetailsService;



@Autowired

private AuthenticationSuccessHandler customAuthenticationSuccessHandler;



@Autowired

private AuthenticationFailureHandler customAuthenticationFailureHandler;



@Autowired

private Authentication authentication;



@Bean

public PasswordEncoder passwordEncoder() {

    return new BCryptPasswordEncoder();

}

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth.userDetailsService(userDetailsService);

}

@Override

protected void configure(HttpSecurity http) throws Exception {

    // 表单登录方式

    http.formLogin()

        .loginPage(authentication.getLoginPage())

        // 登录表单提交处理url, 默认是/login

        .loginProcessingUrl(authentication.getLoginProcessingUrl())

        //验证账号

        .usernameParameter(authentication.getUsername())

        //验证密码

        .passwordParameter(authentication.getPassword())

        //指定访问成功/失败的处理类

        .successHandler(customAuthenticationSuccessHandler)

        .failureHandler(customAuthenticationFailureHandler)

        .and()

        .authorizeRequests()

        ///login/page所有人都能访问,要不没法登录

        .antMatchers(authentication.getLoginPage()).permitAll()

        //其余接口必须验证用户才能访问

        .anyRequest().authenticated()

    ;

}


@Override

public void configure(WebSecurity web){

    web.ignoring().antMatchers(&#34;/dist/\*\*&#34;, &#34;/modules/\*\*&#34;, &#34;/plugins/\*\*&#34;);

}

}

4.5 CustomAuthenticationSuccessHandler /CustomAuthenticationFailureHandler

当验证成功和失败,调用该类,鉴于目前开发都是前后端分离,前端需根据后端返回处理逻辑,此处配置为提供json返回,如果删除该类,会再在页面抛出异常而不是跳转页面。

代码语言:java
复制
@Component("customAuthenticationSuccessHandler")

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

@Override

public void onAuthenticationSuccess(HttpServletRequest request,

    HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

    // 认证成功后,响应JSON字符串

    Result result = Result.ok(&#34;认证成功&#34;);

    //此处指定返回对象为json,也可以改为返回值

    response.setContentType(&#34;application/json;charset=UTF-8&#34;);

    response.getWriter().write(result.toJsonString());

}

}

@Component("customAuthenticationFailureHandler")

public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {

@Override

public void onAuthenticationFailure(HttpServletRequest request,

        HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

    // 认证失败响应JSON字符串,

    Result result = Result.build(HttpStatus.UNAUTHORIZED.value(), exception.getMessage());

    //此处指定返回对象为json,也可以改为返回值

    response.setContentType(&#34;application/json;charset=UTF-8&#34;);

    response.getWriter().write(result.toJsonString());

}

}

4.6 application.yml

springboot配置,配置跳转页面等。

代码语言:java
复制
server:

port: 80

spring:

thymeleaf:

cache: false #关闭thymeleaf缓存

authentication:

loginPage: /login/page

loginProcessingUrl: /login/form # 登录表单提交处理的url

username: name # 登录表单提交的用户名的属性名

password: pwd # 登录表单提交的密码的属性名

staticPaths: # 静态页面放弃拦截

  • /dist/**

  • /modules/**

  • /plugins/**

4.7 Controller

controller作为对外访问入口,同时跳转访问thymeleaf页面。

代码语言:java
复制
@Controller

public class CustomLoginController {

@RequestMapping(&#34;/login/page&#34;)

public String toLogin() {

    return &#34;login&#34;;

}

}

@Controller

public class MainController {

@RequestMapping({&#34;/index&#34;, &#34;/&#34;, &#34;&#34;})

public String index() {

    return &#34;index&#34;;

}

}

4.7 验证

启动项目后,访问localhost,通过配置会跳转到/login/page,此时执行登录即可。

当访问成功/失败会跳转页面并抛出异常,application/json这种返回方式适用于前后端分离,前端通过后端返回执行逻辑。

如果删除CustomAuthenticationSuccessHandler /CustomAuthenticationFailureHandler ,就会在页面抛出异常,而不是跳转页面。

5.总结

目前博主已经体验了很久Cloud Studio,在使用过程中有以下的观点:

  1. Cloud Studio提供了大量的语言模板,如果您是全栈爱好者,有时候还想玩玩python,那么Cloud Studio不用您安装各种环境,开箱及用。
  2. Cloud Studio 作为 Web IDE/在线 IDE/Cloud IDE,和本地 IDE 相比具有以下优势:无需安装,跨平台,只要有浏览器就可以使用;预置常用环境,无需手动安装;支持创建网页预览,在线开发调试,节省电脑资源,Cloud Studio运行速度不和硬件钩挂,多年前老电脑也能流畅运行。
  3. 提供求助场外观众功能,可以请到各种大神为您现场办公。.
  4. 提供云部署套件,配合腾讯云服务+coding代码仓库,中小企业轻松落地devops生态。
  5. 持续的功能扩展,AI编程等功能不定时迭代。

到是在使用过程博主还想提一些建议:

  1. Cloud Studio风格目前与vs code很贴近,那么后端使用idea的小伙伴可能有点不太熟悉,未来能否提供多种风格供使用者选择。
  2. 不能配置项目结构,后端父子依赖工程构建比较复杂。

先阶段Cloud Studio免费试用,Cloud Studio 团队基于老用户使用体验角度和新用户上手成本考虑,现实行每月赠送 3000 分钟的工作空间免费时长 ,具体内容可参考产品文档。小伙伴们还不去体验一下吗。点我点我