Pesquisa de site

Exemplo de autorização de acesso baseado em função de segurança do Spring


Hoje, examinaremos o exemplo de autorização e acesso baseado na função de segurança do Spring. No entanto, antes de ler este post, leia meu post anterior sobre \Exemplo de logout de login do Spring 4 Security MVC para obter algum conhecimento básico sobre o Spring 4 Security.

Função de segurança do Spring

Nesta postagem, discutiremos como definir, usar e gerenciar as funções de segurança do Spring como \USER, \ADMIN no Spring Web Application. Como meu post anterior, este exemplo de post também está usando Spring 4 MVC Security com In-Memory Store e Spring Java Configuration Feature para desenvolver o aplicativo. Isso significa que não vamos usar o arquivo web.xml e também não vamos escrever nem uma única linha de configuração Spring XML. Usaremos a opção \In-Memory Store para armazenar e gerenciar as credenciais do usuário. Usaremos Spring 4.0.2.RELEASE, Spring STS 3.7 Suite IDE, Spring TC Server 3.1 com Java 1.8 e ferramenta de compilação Maven para desenvolver isso exemplo.

Exemplo de autorização de acesso baseado em função de segurança do Spring

  1. Crie um projeto \Simple Spring Web Maven no Spring STS Suite com os seguintes detalhes. Nome do projeto: SpringMVCSecruityMavenRolesApp2. Use o mesmo arquivo pom.xml da minha postagem anterior com as seguintes alterações

<artifactId>SpringMVCSecruityMavenRolesApp</artifactId>

<build>
  <finalName>SpringMVCSecruityMavenRolesApp</finalName>
</build>
</project>

  1. Use todos os arquivos Java e JSP do meu post anterior. Discutiremos apenas o conteúdo atualizado ou adicionado recentemente aqui.
  2. Atualize o arquivo LoginSecurityConfig.java para configurar funções de usuário como \USER e \ADMIN. LoginSecurityConfig.java

package com.journaldev.spring.secuity.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
		authenticationMgr.inMemoryAuthentication()
			.withUser("jduser").password("jdu@123").authorities("ROLE_USER")
			.and()
			.withUser("jdadmin").password("jda@123").authorities("ROLE_USER","ROLE_ADMIN");
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {

		
		http.authorizeRequests()
			.antMatchers("/homePage").access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
			.antMatchers("/userPage").access("hasRole('ROLE_USER')")
			.antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")
			.and()
				.formLogin().loginPage("/loginPage")
				.defaultSuccessUrl("/homePage")
				.failureUrl("/loginPage?error")
				.usernameParameter("username").passwordParameter("password")				
			.and()
				.logout().logoutSuccessUrl("/loginPage?logout"); 
		
	}
}

Explicação do código

  1. No método configureGlobal(), adicionamos dois usuários: um usuário com a função \ROLE_USER e outro usuário com as funções \ROLE_USER e \ROLE_ADMIN. Isso significa que este segundo usuário atuará como um usuário administrador . Assim, podemos configurar qualquer número de usuários e funções.
  2. Podemos usar métodos de autoridades (ROLE) ou funções (ROLE) para configurar funções em nosso aplicativo.
  3. Diferença entre os métodos autoridades() e funções():

  • authorities() precisa do nome completo da função como \ROLE_USER”
  • roles() precisa de um nome de papel como \USER. Ele adicionará automaticamente o valor \ROLE_ a esse nome de papel \USER.

  1. No método configure(), definimos URLs diferentes com funções de acesso necessárias.

antMatchers("/homePage")
   .access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")

Este trecho de código configura que \/homePage está disponível para funções de USUÁRIO e ADMIN.

 .antMatchers("/userPage").access("hasRole('ROLE_USER')")
 .antMatchers("/adminPage").access("hasRole('ROLE_ADMIN')")

Este trecho de código configura que \/userPage é acessível apenas pela função \USER e .\/adminPage é acessível apenas pela função \ADMIN. Se outras funções acessarem essas páginas, obteremos a mensagem de erro \403 Acesso negado.

  1. Atualize o arquivo do controlador LoginController.java para definir novos caminhos de acesso à URL, conforme mostrado abaixo. LoginController.java

package com.journaldev.spring.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

	@RequestMapping(value = { "/"}, method = RequestMethod.GET)
	public ModelAndView welcomePage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("welcomePage");
		return model;
	}

	@RequestMapping(value = { "/homePage"}, method = RequestMethod.GET)
	public ModelAndView homePage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("homePage");
		return model;
	}
	
	@RequestMapping(value = {"/userPage"}, method = RequestMethod.GET)
	public ModelAndView userPage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("userPage");
		return model;
	}
	
	@RequestMapping(value = {"/adminPage"}, method = RequestMethod.GET)
	public ModelAndView adminPage() {
		ModelAndView model = new ModelAndView();
		model.setViewName("adminPage");
		return model;
	}
	
	@RequestMapping(value = "/loginPage", method = RequestMethod.GET)
	public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error,
	@RequestParam(value = "logout",	required = false) String logout) {
		
		ModelAndView model = new ModelAndView();
		if (error != null) {
			model.addObject("error", "Invalid Credentials provided.");
		}

		if (logout != null) {
			model.addObject("message", "Logged out from JournalDEV successfully.");
		}

		model.setViewName("loginPage");
		return model;
	}

}

Explicação do código Além do exemplo do post anterior, aqui adicionamos mais duas novas URLs.

  1. \/userPage é usado pela função USER para acessar e executar atividades normais do usuário.
  2. \/adminPage é usado pela função ADMIN para acessar e executar atividades do usuário Admin. A função ADMIN pode acessar a URL \/userPage também.
  3. Arquivo homePage.jsp atualizado para fornecer atividades específicas de funções de usuário e administrador. homePage.jsp

<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<a href="${pageContext.request.contextPath}/userPage">JD User</a> | <a href="${pageContext.request.contextPath}/adminPage">JD Admin</a> | <a href="javascript:document.getElementById('logout').submit()">Logout</a>

<h3>Welcome to JournalDEV Tutorials</h3>
<ul>
   <li>Java 8 tutorial</li>
   <li>Spring tutorial</li>
   <li>Gradle tutorial</li>
   <li>BigData tutorial</li>
</ul>

<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>

Aqui, adicionamos três opções de menu no quadro superior. \Logout já foi discutido em meu post anterior. Novos dois links são:

  1. Usuário JD: Acessível pelas funções \USER e \ADMIN
  2. JD Admin: Acessível apenas por ambas as funções \ADMIN

NOTA:- Em aplicações de tempo real, mostraremos apenas o link \JD User para a função \USER e ocultaremos o link \JD Admin. Para testar se é acessível pela função \USER ou não e também para ver a mensagem de erro exata, não ocultamos este link.20. Inclua o novo arquivo adminPage.jsp para atuar como uma página inicial para a função \ADMIN.

<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>Admin Page</h3>

<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
	<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>

  1. Adicione o novo arquivo userPage.jsp para atuar como uma página inicial para a função \USER. userPage.jsp

<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<h3>Welcome to JournalDEV Tutorials</h3>
<h3>User Page</h3>

<c:url value="/logout" var="logoutUrl" />
<form id="logout" action="${logoutUrl}" method="post" >
  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
	<a href="javascript:document.getElementById('logout').submit()">Logout</a>
</c:if>

Concluímos o desenvolvimento de nosso aplicativo agora. É hora de ver a estrutura final do nosso projeto e testar a aplicação.26. A estrutura final do projeto fica assim:

Teste de aplicativo de exemplo de funções de segurança do Spring

Isso é tudo sobre o exemplo de funções de segurança do Spring para fornecer acesso autorizado a páginas de aplicativos da web.