I want to add css, javascript and images to a spring 4 web application, i could give an example but I'm trying a spring tutorial:
Securing Web - http://spring.io/guides/gs/securing-web/
I added following changes:
package hello;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Then i added a folder css with a simple css to the resources folder:
#CHARSET "ISO-8859-1";
p {
border-style:solid;
border-width:5px;
}
Then i added the css to the home.html:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Example</title>
<link type="text/css" rel="stylesheet" href="/resources/css/dummy.css"></link>
</head>
<body>
<h1>Welcome!</h1>
<p>Click <a th:href="#{/hello}">here</a> to see a greeting.</p>
</body>
</html>
Security config is injected through the following java class:
package hello;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
#Configuration
#EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated();
http
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
Then when using the google debug it returns the code
Status Code:302 Found but the css is not applied.
Could anyone indicate the changes necessary to add to make this working?
Discovered the problem after some search, the changes need to be able to use the css in the example are:
Create the following dirs under src/main:
- webapp
- resources
- css
Then add the dummy.css and in the desired html use:
<link th:href="#{/resources/css/dummy.css}" type="text/css" rel="stylesheet" href="/resources/css/dummy.css"></link>
Thanks to everyone that tried to help :)
Related
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Welcome to Akash Home</title>
<link rel="stylesheet" type="text/css"
href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript"
src="/webjars/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container text-center">
<h1>Welcome to the portal</h1>
<h3>
Register
</h3>
<h3>
Login as a admin<br>
Login as a user<br>
<!-- login -->
logout
</h3>
</div>
</body>
</html>
Here I am creating separate links for login as an admin/user. How do I add a single login page that redirects to the next page according to the credential entered for ex: if user1 is an admin if his credentials are entered he will be redirected to the admin page and vise-versa for a user login
here is my spring security config code :
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public UserDetailsService getUserDetailService() {
return new UserDetailsServiceImpl();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(this.getUserDetailService());
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
return daoAuthenticationProvider;
}
// authentication - configure method
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/show-menu-list-admin").hasRole("ADMIN")
.antMatchers("/show-menu-list-customer").hasRole("USER").and().formLogin().and().csrf().disable();
}
}
You can supply a custom AuthenticationSuccessHandler.
The AuthenticationSuccessHandler is what tells Spring Security what to do after a successful user authentication.
The default implementation typically uses a SimpleUrlAuthenticationSuccessHandler, which redirects users to the supplied URL once they successfully authenticate.
In your custom implementation, you can delegate to a different SimpleUrlAuthenticationSuccessHandler based on the user's role.
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
SimpleUrlAuthenticationSuccessHandler userSuccessHandler =
new SimpleUrlAuthenticationSuccessHandler("/user-page");
SimpleUrlAuthenticationSuccessHandler adminSuccessHandler =
new SimpleUrlAuthenticationSuccessHandler("/admin-page");
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (final GrantedAuthority grantedAuthority : authorities) {
String authorityName = grantedAuthority.getAuthority();
if (authorityName.equals("ROLE_ADMIN")) {
// if the user is an ADMIN delegate to the adminSuccessHandler
this.adminSuccessHandler.onAuthenticationSuccess(request, response, authentication);
return;
}
}
// if the user is not an admin delegate to the userSuccessHandler
this.userSuccessHandler.onAuthenticationSuccess(request, response, authentication);
}
}
Then, supply the CustomAuthenticationSuccessHandler in the form login configuration.
http
.formLogin(formLogin -> formLogin
.successHandler(new CustomAuthenticationSuccessHandler())
);
I'm working on MVC web app. Using Spring Boot 2.0.1 with Spring Security.
And I get error 404 when try reaching static resources.
I've tried diefferent things, I've read many topics, but can't find any solution.
Configuretion class:
#SpringBootApplication
#EnableWebMvc
public class FriendlyFireChessApplication extends SpringBootServletInitializer implements WebMvcConfigurer {
#Autowired
private SpringApplicationContext springApplicationContext;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(FriendlyFireChessApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(FriendlyFireChessApplication.class, args);
}
/*
some beans here
*/
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Project strucutre:
index.html:
<DOCTYPE html>
<html lang="en">
<head>
<title>Friendly fire chess</title>
<link rel="stylesheet" type="text/css" href='/static/css/style.css'/>
</head>
<body>
<header>
<div class="main_header">
<div>
<a id="icon"><img src='/static/img/logo_1.png' width="40" height="70" border="0" /></a>
</div>
<div id="main_title">
<span>Friendly Fire Chess</span>
</div>
<div class="authentication_bar">
<div>
<span><a id="log_in_button" href='http://www.ffchess.org/login'>Login</a></span>
</div>
<div>
<span><a id="sign_in_button" href="http://www.ffchess.org/signin">Sign In</a></span>
</div>
</div>
</div>
</header>
</html>
Security settings:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL)
.permitAll()
.antMatchers(HttpMethod.GET, SecurityConstants.VERIFICATION_EMAIL_URL)
.permitAll()
.antMatchers(HttpMethod.POST, SecurityConstants.PASSWORD_RESET_REQUEST_URL)
.permitAll()
.antMatchers(HttpMethod.POST, SecurityConstants.PASSWORD_RESET_URL)
.permitAll()
.antMatchers(SecurityConstants.H2_CONSOLE)
.permitAll()
.antMatchers(SecurityConstants.HOME_PAGE)
.permitAll()
.antMatchers("/resources/**", "/static/css/**", "/static/img/**")
.permitAll()
.anyRequest().authenticated().and()
.addFilter(getAuthenticationFilter())
.addFilter(new AuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
What's wrong with all of this?
As per project structure, all your resources will be copied to static directory under your classpath and there won't be any location like resources. Hence, it would not be able to resolve.
resource location should be specified along with classpath
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
for safer side, you can class multiple location lookup as well like this
.addResourceLocations(new String[]{"classpath:/static/", "/"});
Spring includes these by default unless overridden
["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
I have configured all the settings for my spring project, but when I try to login in to the application, it says for each request that
"The server understood the request but refuses to authorize it."
Initially I tried to implement JDBC Authentication, (you can see that I am using the Datasource in my code). But then I tried with in memory authentication too, in both cases, I am unable to access the resources.
Below is my spring config file,
package com.nobalg.config;
import java.beans.PropertyVetoException;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.mchange.v2.c3p0.ComboPooledDataSource;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.nobalg")
#PropertySource("classpath:persistence-mysql.properties")
public class AppConfig {
#Autowired
private Environment env;
private Logger logger = Logger.getLogger(getClass().getName());
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public DataSource secureDataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
//Datasource
dataSource.setDriverClass(env.getProperty("jdbc.driver"));
dataSource.setJdbcUrl(env.getProperty("jdbc.url"));
dataSource.setUser(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.password"));
//Connection polling
dataSource.setInitialPoolSize(Integer.parseInt(env.getProperty("connection.pool.initialPoolSize")));
dataSource.setMaxPoolSize(Integer.parseInt(env.getProperty("connection.pool.maxPoolSize")));
dataSource.setMinPoolSize(Integer.parseInt(env.getProperty("connection.pool.minPoolSize")));
dataSource.setMaxIdleTime(Integer.parseInt(env.getProperty("connection.pool.maxIdleTime")));
} catch (PropertyVetoException e) {
throw new RuntimeException(e);
}
return dataSource;
}
}
Dispatcher Servlet Initializer file
package com.nobalg.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MvcSpringInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class[]{AppConfig.class};
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[]{"/"};
}
}
Spring security configuration file :
package com.nobalg.config;
import javax.sql.DataSource;
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 SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//auth.jdbcAuthentication().dataSource(dataSource);
auth.inMemoryAuthentication().withUser("Nobal").password("test#123").authorities("MANAGER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/loginPage")
.loginProcessingUrl("/loginProcessing")
.usernameParameter("username")
.passwordParameter("password")
.permitAll();
}
}
Spring security initializer file
package com.nobalg.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
The one and only controller
package com.nobalg.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
#Controller
public class MainContoller {
#GetMapping("/loginPage")
public String showLoginForm(){
return "login";
}
}
and the login page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form:form method="POST" action="${pageContext.request.contextPath}/loginProcessing">
<p>Enter Username : <input type="text" placeholder="Enter Username" name="username"></p>
<p>Enter Password : <input type="password" placeholder="Enter Password" name="password"></p>
<p><input type="submit" value="LOG IN"></p>
</form:form>
</body>
</html>
Add this as your form field:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
Or if you want other approach with Spring Security JSP tag library:
Optionally you can disable csrf, which is enabled by default:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
Edit1
Add this bean with passwordEncoder.
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
And set password encoder to auth:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.passwordEncoder(this.passwordEncoder());
}
Edit2
Change .loginProcessingUrl("/loginProcessing") which needs UserDetailsService to .defaultSuccessUrl("/")
I'm actually learning Spring Boot. I follow the guides and i'm tryng this one : Securing a Web Application.
So I've made 2 files (hello.html/home.html) and i would like to deploy my application to see them but when i try to access localhost:8080 i get this error :
Circular view path [home]: would dispatch back to the current handler URL [/home] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
If someone can help me there ? Here is my code :
src/main/java/com/society/MyApplication :
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MyApplication {
public static void main(String[] args) throws Throwable {
SpringApplication.run(CalamarApplication.class, args);
}
}
src/main/java/com/society/MvcConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}
src/main/resources/templates/home.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
Thanks by advance.
I am getting this error while adding Assets folder.
It is giving error for every file which is included from "assets" folder.
WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/assets/plugins/datepicker/datepicker3.css] in DispatcherServlet with name 'dispatcher'
Here is the Dispacther Config file
package com.springmaven.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan({"com.springmaven.controller"})
public class DispatcherConfig {
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver()
{
InternalResourceViewResolver internalResourceViewResolver=new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("/WEB-INF/JSP/");
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
}
This is App Config
package com.springmaven.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppIntializer implements WebApplicationInitializer{
#Autowired
public void onStartup(ServletContext servletCon) throws ServletException {
// TODO Auto-generated method stub
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationConfig.class);
servletCon.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext servletConfig = new AnnotationConfigWebApplicationContext();
servletConfig.register(DispatcherConfig.class);
ServletRegistration.Dynamic registration = servletCon.addServlet("dispatcher", new DispatcherServlet(servletConfig));
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
This is security Config
package com.springmaven.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private AuthenticationProvider customAuthenticationProvider;
#Autowired
CustomSuccessHandler customSuccessHandler;
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/assets/**");
}
#Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(customAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/assets/**").permitAll()
.and()
.formLogin().loginPage("/loginPage")
.defaultSuccessUrl("/homePage")
.failureUrl("/loginPage?error")
.usernameParameter("username").passwordParameter("password")
.and().csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.logout().logoutSuccessUrl("/loginPage?logout");
}
#Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
private CsrfTokenRepository csrfTokenRepository()
{
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setSessionAttributeName("_csrf");
return repository;
}
}
Folder Structure
source->main->webapp->WEB-INF->JSP->assets(This folder is not recognised)
source->main->webapp->WEB-INF->JSP->homePage.jsp
From the Style or Icon is not coming in homePage.
homePage.jsp
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>New Member</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.5 -->
<!--Favicon Image -->
<link rel="shortcut icon" href="assets/dist/img/favicon.ico"/>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" href="assets/plugins/datepicker/datepicker3.css">
</head>
<body>
Welcome,
<form id="logout" action="${Signout}" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<c:if test="${pageContext.request.userPrincipal.name != null}">
Logout
</c:if>
</body>
</html>
You need to add support for static web resources.
To configure it to be managed by Spring see this question, for example.