Sec:authorize doesn't work in spring security 4 - spring-boot

i'm trying to use spring security. I created two users in memory admin and users.
auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
This is my pom.xml:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
and this is my html page:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/myStyle.css"/>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script type="text/javascript" src="js/myApp.js"></script>
<link rel="stylesheet" href="css/print.css" type="text/css" media="print" />
</head>
<body ng-app="myStockApp">
<div ng-controller="mainctr">
<div data-ng-init="listArticles()">
<div sec:authorize="hasRole('ROLE_ADMIN')">Only for admin</div>
//code ...
I would like that only the admin sees that div, but when i logged as a user, the div above appears, or it should be disappear. can you tell me where is the probleme ? thank you.

Could you replace in thymeleaf this
<div sec:authorize="hasRole('ROLE_ADMIN')">Only for admin</div>
with the following
<div sec:authorize="hasAuthority('ADMIN')">Only for admin</div>
and let me know if it works for you.

make sure that you are using spring security 4, if you don't change your thymeleaf-extras-springsecurity for the correct one

after searching and trying to understand the problem i found out that there is a problem with the dialect
you can see here how to add the dialect:
How do I add Thymeleaf SpringSecurityDialect to spring boot
tl;dr
add this to your config
#Bean
public SpringSecurityDialect securityDialect() {
return new SpringSecurityDialect();
}

Related

Spring MVC and Thymeleaf - only classpath mapping works

I wonder why I have to add "classpath:" always int he resourcelocations mapping for Spring, is this best practice?
Currently my project is setup like this, but I if I remove the "classpath", it does not find anything (and also I cannot provide a proper direct link). For integating bootstrap, I even had to use "webjars-locator" to make webjars accessible (due to missing transparency).
Can anyone explain, why classpath is required (and no direct link), and how I can find or restrucutre the project to make it work properly?
ResourceHandlers:
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler(
"/webjars/**",
"/img/**",
"/css/**",
"/js/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/",
"classpath:/static/img/",
"classpath:/static/css/",
"classpath:/static/js/");
}
index.htm:
<!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>Spring Security Example</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" th:href="#{/css/style.css}" />
<link rel="stylesheet" type="text/css" th:href="#{/webjars/bootstrap/4.2.1/css/bootstrap.min.css}" />
</head>
<body>
<h1 class="color1">Hello, world! style</h1>
<p>
Click <a th:href="#{/hello}">here</a> to see a greeting.
</p>
<!-- include javascript in the footer -->
**<script type="text/javascript" th:src="#{/webjars/jquery/3.2.1/jquery.min.js}"></script>
<script type="text/javascript" th:src="#{/webjars/bootstrap/4.2.1/js/bootstrap.min.js}"></script>**
</body>
</html>
It is normal to use classpath. If you want to additionally load resources from root path use
{"/", "classpath:/META-INF/resources/webjars/" ...}

IntelliJ Spring Boot project can't find my CSS files with Thymeleaf

I'm new to Spring Boot and my problem is that I have Spring Boot project and I am intending to view my HTML pages with Thymeleaf but Spring can't resolve my JavaScript and CSS files.
Full picture of my IDE:
Those are my Thymeleaf configurations
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=true
This is my HTML page head:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
>
<head>
<title>404 Page</title>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--[if lt IE 9]>
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1"/>
<meta name="viewport" content="width=device-width"/>
<!-- Css Files Start -->
<link href="/src/main/resources/static/css/style.css" rel="stylesheet" type="text/css" media="screen"/><!-- All css -->
<link href="/src/main/resources/static/css/bs.css" rel="stylesheet" type="text/css" media="screen"/><!-- Bootstrap Css -->
<link rel="stylesheet" type="text/css" href="/src/main/resources/static/css/main-slider.css" media="screen"/><!-- Main Slider Css -->
<!--[if lte IE 10]>
<link rel="stylesheet" type="text/css" href="/static/css/customIE.css" media="screen"/><![endif]-->
<link href="/src/main/resources/static/css/font-awesome.css" rel="stylesheet" type="text/css" media="screen"/><!-- Font Awesome Css -->
<link href="/src/main/resources/static/css/font-awesome-ie7.css" rel="stylesheet" type="text/css" media="screen"/><!-- Font Awesome iE7 Css -->
<noscript>
<link rel="stylesheet" type="text/css" href="/static/css/noJS.css"/>
</noscript>
<!-- Css Files End -->
</head>
You should use relative path to your JavaScript and CSS files:
<link href="../../static/css/style.css" rel="stylesheet" type="text/css" media="screen"/>
or you can use th:href Thymeleaf's tag as well:
<link th:href="#{css/style.css}" href="../../static/css/style.css"
rel="stylesheet" type="text/css" media="screen"/>
I have found that Spring automatically searches for: /resources/.
So what I did was removed all the pre-directories by using find all.
So, in my case what used to be for example: /static/css/style.css & /templates/index.html
became: /css/style.css & /index.html
Now the question remains how does Spring boot know what folder to look in without you defining it: Spring looks at the extension. When spring boot sees .html, it looks for it in a folder called /templates.

Use different css or java script per page with freemarker

Using FreeMarker, I would like to be able to load different stylesheets or javascript files in different templates. My problem may be in my implementation.
I have a single layout macro which looks like this:
<#macro layout>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- common javascript and css references here -->
</head>
<body>
<div class="container">
<!-- header stuff -->
<#nested>
<!-- footer stuff -->
</div>
</body>
</html>
</#macro>
I use this in all templates like this:
<!-- "declare" specific css or js here -->
<#layout.layout>
<div id="mapid">
<!-- use specific css or js -->
</div>
</#layout.layout>
In some of my templates I would like to use specific stylesheets or javascript libraries that apply to the common case. What is the best approach for this?
I've tried passing variable in to the layout macro to insert the css and js references but I've found no easy way to assign a block of text using #assign.
You can declare nested tags and send as a parameter the name like this:
layout.ftl
<#macro layout>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- common javascript and css references here -->
<#nested "styles">
<#nested "scripts">
</head>
<body>
<div class="container">
<!-- header stuff -->
<#nested "content">
<!-- footer stuff -->
</div>
</body>
</html>
</#macro>
And then you can receive as a parameter the section and use an if like this:
page.ftl
<#layout.layout; section>
<#if section = "scripts">
<script src="/js/myscripts/myfile.js"></script>
</#if>
<#if section = "styles">
<link rel="stylesheet" href="/css/style.css" />
</#if>
<#if section="content">
<div id="mapid">
</div>
</#if>
</#layout.layout>
I separated the layout into page start end page end, and define the nested in page start.
page_start.ftl
<#macro external>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>${title}</title>
<meta name="keywords" content="${keyword}">
<meta name="description" content="${description}">
<link href="https://cdn.insdep.com/themes/1.0.0/easyui.css" rel="stylesheet" type="text/css">
<link href="https://cdn.insdep.com/themes/1.0.0/easyui_animation.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="https://cdn.insdep.com/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="https://cdn.insdep.com/easyui/jquery.easyui-1.5.1.min.js"></script>
<#nested >
</head>
<body>
<#include "global/header.ftl">
<#include "global/sidebar.ftl">
</#macro>
page_end.ftl
<#include "global/footer.ftl">
</body>
</html>
<#import "page_start.ftl" as page>
<#page.external>
<link href="https://cdn.insdep.com/themes/1.0.0/easyui_plus.css" rel="stylesheet" type="text/css">
</#page.external>
hello world
<#include "page_end.ftl">
But I do think, this is not a very decent solution.

How can I correctly import an header and a footer page into a FreeMarker page?

I am working on a Spring MVC application that use FreeMarker for my views.
I am absolutly new in FreeMarker and I have the following problem: in my projct I have 3 files that have to be assemblet togheter into a single page.
So I have:
1) header.ftl representing the header of all my pages, somthing like:
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js is-ie8"><![endif]-->
<!--[if gt IE 8]><!--><html class="no-js"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Registrazione - MY WEBSITE</title>
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" href="resources/css/webfont.css">
<link rel="stylesheet" href="resources/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="resources/bootstrap/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="resources/plugins/bs-select/bootstrap-select.min.css">
<link rel="stylesheet" href="resources/plugins/bs-dialog/bootstrap-dialog.min.css">
<link rel="stylesheet" href="resources/css/style.css" />
</head>
<body id="main">
<!-- versione per popup. non prendere in considerazione -->
<!--
<div class="container page-header">
<h1>MY WEBSITE</h1>
</div>
2) footer.ftl representing the footer of all my pages:
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/plugins/bs-select/bootstrap-select.min.js"></script>
<script src="assets/plugins/bs-select/i18n/defaults-it_IT.min.js"></script>
<script src="assets/plugins/bs-dialog/bootstrap-dialog.min.js"></script>
<script src="assets/plugins/jq-form-validation/jquery.validation.js"></script>
<script src="assets/js/functions.lib.js"></script>
<script src="assets/js/form-validation.js"></script>
</body>
</html>
3) Then I have my specific page (named myPage.ftl that represent only the content, something like this:
<h1>This is the content</h1>
<p>Some inforamation</p>
The header.ftl and the footer.ftl are into this directory **\WEB-INF\freemarker\layout** of my project.
So my problem is: how can I import the header.ftl content above the content of the myPage.ftl and the footer.ftl under the content of myPage.ftl page?
I did this using user-defined macros for page layouts, e.g. let's call your layout standardPage.ftl:
<#macro standardPage title="">
<!DOCTYPE html>
<html lang="en">
<head>
<title>${title}</title>
</head>
<body>
<#include "/include/header.ftl">
<#nested/>
<#include "/include/footer.ftl">
</body>
</html>
</#macro>
Then you can call this macro in each of your pages, e.g. homePage.ftl:
<#include "/pages/standardPage.ftl" />
<#standardPage title="Home">
<h1>Home Page</h1>
<p>This bit replaces the nested tag in the layout</p>
</#standardPage>

Respond.js with twitter bootstrap on ie8 and below

i'm implementing a responsive website with twitter bootstrap but on iexplorer 8 and below can't use media queries.
I create a simple example for try respond.js but mediaqueries continue not working on iexplorer 7-8, here is the html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>Bootstrap 101 Template</title>
<meta name="Description" content="Web description here" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="./css/styles.css" rel="stylesheet">
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="shortcut icon" href="./img/favicon.png">
</head>
<body>
<div class="container">
<h1>Hello, world!</h1>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="./js/respond.min.js"></script>
<script src="./js/scripts.js"></script>
</body>
</html>
and here is the style.css:
#media only screen and (max-width: 38.75em) {
body {
background: green;
}
}
Regards
https://github.com/scottjehl/Respond#cdnx-domain-setup
CDN/X-Domain Setup
Respond.js works by requesting a pristine copy of your CSS via AJAX, so if you host your stylesheets on a CDN (or a subdomain), you'll need to upload a proxy page to enable cross-domain communication.
See cross-domain/example.html for a demo:
Upload cross-domain/respond-proxy.html to your external domain
Upload cross-domain/respond.proxy.gif to your origin domain
Reference the file(s) via <link /> element(s):
<!-- Respond.js proxy on external server -->
<link href="http://externalcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
<!-- Respond.js redirect location on local server -->
<link href="/path/to/respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
<!-- Respond.js proxy script on local server -->
<script src="/path/to/respond.proxy.js"></script>
If you are having problems with the cross-domain setup, make sure respond-proxy.html does not have a query string appended to it.
Note: HUGE thanks to #doctyper for the contributions in the cross-domain proxy!
You need to include <script src="./js/respond.min.js"></script> above the </head> tag.
If you don't want to add any code related with respond.js, load bootstrap.min.css through CDN except for IE 8. For IE 8, use local static file.
<!--[if lte IE 8]>
<link rel="stylesheet" href="/path/to/bootstrap.min.css' %}" />
<![endif]-->
<!--[if gt IE 8]>
<link rel="stylesheet" href="{CDN Address}" />
<![endif]-->
<!--[if !IE]><!-->
<link rel="stylesheet" href="{CDN Address}" />
<!--<![endif]-->
Tested on IE 8 ~ 11 and other webkit browsers.

Resources