Spring Boot安全保护使用教程

栏目: Java · 发布时间: 5年前

内容简介:在这篇文章中,我将解释Spring如何管理安全性。当然,我不会涵盖所有内容 - 安全问题将可以写成一本大书,但我们至少会看看如何保护网站。如何使用两个Java类及其HTML文件来保护您的网页。Spring Boot实际上非常简单,因为我们只要使用Spring的启动器即可,启动器包括Web,Thymeleaf,当然还有Security。这些启动器会打包在pom.xml文件中。

在这篇文章中,我将解释Spring如何管理安全性。当然,我不会涵盖所有内容 - 安全问题将可以写成一本大书,但我们至少会看看如何保护网站。如何使用两个 Java 类及其HTML文件来保护您的网页。

Spring Boot实际上非常简单,因为我们只要使用Spring的启动器即可,启动器包括Web,Thymeleaf,当然还有Security。

这些启动器会打包在pom.xml文件中。

Thymeleaf 是与Spring无缝集成并创建网页模板的软件,它与JSP类似,但Thymeleaf是一个更加改进的版本。或者,更像JSF,更JavaEE一些。案例中使用它的HTML页面与Spring的类无缝集成。

如果我们要在网页中看到登录的用户名,就需要使用库安全的Thymeleaf for Spring。为此,我们将在pom.xml文件中包含以下行。

<dependency>
  <groupId> org.thymeleaf.extras <groupId/>
  <artifactId> thymeleaf-extras-springsecurity4 <artifactId/>
  <version> 3.0.3.RELEASE <version/>
<dependency/>

现在,我们开始声明我们的第一个类,我称之为 WebSecurityConfiguration.java:

@SpringBootApplication
@EnableWebSecurity
<b>public</b> <b>class</b> WebSecurityConfiguration <b>extends</b> WebSecurityConfigurerAdapter {
    <b>public</b> <b>static</b> <b>void</b> main (String [] args) {
            SpringApplication.run (WebSecurityConfiguration.<b>class</b>, args);
    }

    @Bean
    @Override
    <b>public</b> AuthenticationManager authenticationManagerBean() throws Exception {
       <b>super</b>.authenticationManagerBean <b>return</b>();
    }

    @Bean
    @Override
    <b>public</b> UserDetailsService userDetailsService() {
         UserDetails user = User.builder()(). Username(<font>"user"</font><font>).Password(passwordEncoder().Encode( </font><font>"secret"</font><font>)).roles ( </font><font>"USER"</font><font>) build().;
         UserDetails UserAdmin = User.builder(). Username(</font><font>"admin"</font><font>).Password(passwordEncoder().Encode( </font><font>"secret"</font><font>)).roles ( </font><font>"ADMIN"</font><font>) build().;
        <b>return</b> <b>new</b> InMemoryUserDetailsManager (user, UserAdmin);
    }

    @Bean
    <b>public</b> PasswordEncoder passwordEncoder() {
        <b>return</b> <b>new</b> BCryptPasswordEncoder();
    }

    @Override
    <b>protected</b> <b>void</b> set (http HttpSecurity) throws Exception {
        http
        .csrf().disable()
            .authorizeRequests()
            .antMatchers( </font><font>"/"</font><font> </font><font>"/ index"</font><font>, </font><font>"/ webpublico"</font><font>). permitAll()
            .antMatchers( </font><font>"/ webprivado"</font><font>). authenticated()
            .antMatchers( </font><font>"/ webadmin"</font><font>). hasRole ( </font><font>"ADMIN"</font><font>). and()
                .formLogin()
                .loginPage( </font><font>"/ login"</font><font>)
                .permitAll()
                .and()
                .logout() </font><font><i>// get method for I desabilitado CSRF</i></font><font>
                .permitAll();
    }
}
</font>

标注@SpringBootApplication 和 @EnableWebSecurity。第一个希望使用Spring Boot必注;第二个是指定激活Web安全性; 老实说,这个标签不是必需的,Spring Boot非常聪明,因为我们已经看到了项目中引入了安全性包(在pom.xml中)。但它提供了进一步的清晰度,但是,尽管是多余的。

@SpringBootApplication
@EnableWebSecurity
<b>public</b> <b>class</b> WebSecurityConfiguration <b>extends</b> WebSecurityConfigurerAdapter {

现在,我们指定我们的类将继承自WebSecurityConfigurerAdapter,因为我们会覆盖该类的一些功能。因此,你需要了解Spring并查看是否存在类实现接口WebSecurityConfigurer,后者又实现接口WebSecurityConfigurerAdapter,如果有,则使用该接口的功能来配置安全应用程序。

如果我们有一个实现此接口的类,Spring就不会访问我们应用程序的任何页面,但不是很实用。

@Bean
@Override
<b>public</b> AuthenticationManager authenticationManagerBean() throws Exception {
 <b>super</b>.authenticationManagerBean <b>return</b>();
}

现在,我们需要编写一个函数 authenticationManagerBean 来返回负责管理身份验证的类(顾名思义)。重要的是要知道在哪里获取(注入)对象类型AuthenticationManager, 因为只有通过它你才能控制Spring的安全性。

@Bean
@Override
<b>public</b> UserDetailsService userDetailsService() {
 UserDetails user = User.builder()(). Username(<font>"user"</font><font>).Password(passwordEncoder().Encode( </font><font>"secret"</font><font>)).roles ( </font><font>"USER"</font><font>) build().;
 UserDetails UserAdmin = User.builder(). Username(</font><font>"admin"</font><font>).Password(passwordEncoder().Encode( </font><font>"secret"</font><font>)).roles ( </font><font>"ADMIN"</font><font>) build().;
 <b>return</b> <b>new</b> InMemoryUserDetailsManager (user, UserAdmin);
}
</font>

在userDetailsService,我们定义可以访问我们网站的用户。在这种情况下,我们创建了两个用户:user和admin,每个用户都有自己的密码和角色。角色名称USER和ADMIN可以自己定义,可以是你想要的任何字母。例如,USER_WITH_EYES - 事实是我们一旦使用该角色名,它必须与你定义的角色集合的角色名称逐个字母匹配。

另请注意,在这种情况下,密码是使用算法Bcrypt加密的。我们通过调用函数来完成此操作,该函数 passwordEncoder使用Spring @Bean 标签进行注释。

也就是说,Spring需要知道我们用来存储密码的加密系统,并且它寻找实现接口的对象 PasswordEncoder:

@Bean
<b>public</b> PasswordEncoder passwordEncoder() {
 <b>return</b> <b>new</b> BCryptPasswordEncoder();
}

我想澄清一下,我们使用最简单的方法来声明用户并将其存储在内存中 InMemoryUserDetailsManager。在真实的程序中,它会使用JdbcUserDetailsManager,存储在数据库中。或者可能是包括实现接口UserDetailsManager的任何其他类, 如果我们使用LDAP服务可能会是LdapUserDetailsManager。

@Override
<b>protected</b> <b>void</b> set (http HttpSecurity) throws Exception {
   http.csrf().disable()
            .authorizeRequests()
            .antMatchers( <font>"/"</font><font> </font><font>"/ index"</font><font>, </font><font>"/ webpublico"</font><font>). permitAll()
            .antMatchers( </font><font>"/ webprivado"</font><font>). authenticated()
            .antMatchers( </font><font>"/ webadmin"</font><font>). hasRole ( </font><font>"ADMIN"</font><font>). and()
                .formLogin()
                .loginPage( </font><font>"/ login"</font><font>)
                .permitAll()
                .and()
                .logout() </font><font><i>// get method for I desabilitado CSRF</i></font><font>
                .permitAll();
}
</font>

由于我们需要定义应用程序的哪些部分将受到保护,因此角色必须具有访问其每个部分的权限。是的,是角色而非用户,因为正如我们之前所说,当您定义用户时,您必须分配一个角色。通常,过滤规则是适用于用户所属的组,要为每个资源设置权限,我们要在函数protected void configure(HttpSecurity http)中配置接受的对象HttpSecurity。

我将逐行解释在这个函数中做了什么:

csrf(). disable()

首先,我们正在研究CSRF禁用控制。CRSF代表 跨站点请求伪造, 禁用CRSF有副作用,可以使用HTTP GET请求执行会话注销,然后默认只能通过POST请求完成:

.authorizeRequests ().antMatchers("/","/ index", "/webpublico").permitAll ()

我们指定使用任何字符串“/”,“/ index”,“/ webpublico”等路由的URL将不具有安全性。每个人都可以访问。

antMatchers ("/webprivado").authenticated()

我们指定请求路径“/webprivado”需要用户进行身份验证才能访问,不需要指定属于什么角色。

.antMatchers("/webadmin").hasRole("ADMIN")

只有属于ADMIN角色的用户才能访问URL “/ webadmin”。

该函数antMatchers是可使用正则表达式,因此,例如,如果我们想要将规则应用于依赖于路由的所有规则,我们可以将此:

http.antMatchers(“/ users / **”).hasRole(“USER”)

指定访问URL是/users/XXX的任何请求只能是属于USER角色的用户发出的。

.formLogin().loginPage("/login").permitAll()

我们指定登录页面为“ / login ”并允许其访问所有人。

logout(). permitAll()

我们指定可让所有人访问​​退出页面。默认情况下,此页面由URL“ /logout ”响应。

我们已经定义了我们网站的安全性。现在,我们只要定义页面的入口点。完成类 WebController.java。

@Controller
<b>public</b> <b>class</b> WebController
{
@RequestMapping ({ <font>"/"</font><font>, </font><font>"index"</font><font>})
<b>public</b> String start () {
<b>return</b> </font><font>"index"</font><font>;
}
@RequestMapping ( </font><font>"/webprivado"</font><font>)
<b>public</b> <b>private</b> String () {
</font><font>"Private"</font><font> <b>return</b>;
}
@RequestMapping ( </font><font>"/webpublico"</font><font>)
<b>public</b> String loginpub () {
</font><font>"Public"</font><font> <b>return</b>;
}
@RequestMapping ( </font><font>"/webadmin"</font><font>)
<b>public</b> String admin () {
<b>return</b> </font><font>"admin"</font><font>;
}
@RequestMapping ( </font><font>"/login"</font><font>)
<b>public</b> String login () {
<b>return</b> </font><font>"login"</font><font>;
}
}
</font>

如上所述,@Controller定义Web请求的入口点。

@RequestMapping来指定URL并由每个函数处理。因此,当对URL,“ / ”或“ /index ” 的请求时,将调用函数start。

返回的字符串将是Thymeleaf返回的模板,start函数将返回“index.html”模板,如下所示:

<! DOCTYPE html>
<Html xmlns = <font>"http://www.w3.org/1999/xhtml"</font><font> xmlns: th = </font><font>"http://www.thymeleaf.org"</font><font>
xmlns: sec = </font><font>"http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"</font><font>>
<Head>
<Title> Home Page </ title>
</ Head>
<Body>
<H1> Home Page </ h1>
<P> <a th:href=</font><font>"@{/webpublico}"</font><font>> Click here to view a page </a> <b>public</b>. </ P>
<P> If you are a regular user clicks </a> <a th:href=</font><font>"@{/webprivado}"</font><font>> here to view a <b>private</b> page </ p>
<P> If you are a regular administrator </a> click <a th:href=</font><font>"@{/webadmin}"</font><font>> here to see the profile Administrator </ p>
<Div sec: Authorize = </font><font>"isAuthenticated ()"</font><font>>
Hello <span sec: authentication = </font><font>"name"</font><font>> someone </ span>
<P> <a th:href=</font><font>"@{/logout}"</font><font>> Disconnect </a> </ p>
</ Div>
</ Body>
</ Html>
</font>

它看起来像纯HTML?这是使用Thymeleaf标准HTML标记的优势之一。我不会在这里解释这个语言,但我将解释一些使用的标签:

<a th:href="@{/webpublico}">

创建指向“/webpublico” 的链接。这就像使用“tag <A href="/webpublico">。

<div sec: Authorize = "isAuthenticated ()">

如果用户通过身份验证,这是唯一将在DIV中呈现的代码。换句话说,如果用户未登录,则它不会显示在DIV标签之间的网页上。

<span sec: authentication = "name"> someone </ span>

如果用户使用其用户名登录,则会显示标签span之间的内容。在这种情况下,它显示了某人用户名。

有了这个,我们有一个安全的应用程序!是的,我们只使用两个Java类及其相应的HTML文件来保护网页。

源码: GitHub 


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance JavaScript

High Performance JavaScript

Nicholas C. Zakas / O'Reilly Media / 2010-4-2 / USD 34.99

If you're like most developers, you rely heavily on JavaScript to build interactive and quick-responding web applications. The problem is that all of those lines of JavaScript code can slow down your ......一起来看看 《High Performance JavaScript》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具