Implementing remember me without a key - spring

i found some samples that implements remember me functionality by just
<remember-me/>
and other samples implement it as:
<remember-me key="_spring_security_remember_me"/>
and i want to know what is the difference between the two declarations, and is the _spring_security_remember_me is a predefined key?
thanks.

The default key can be found in AuthenticationConfigBuilder.createRememberMeFilter()
final String DEF_KEY = "SpringSecured";
That is the value that is used if you don't specify one in <remember-me>

From the documentation, the key attribute is used in hashing the value stored in the cookie. It prevents a malicious user from trying to decode the cookie, because they can't do that (well it s a lot harder) without the key.

For anyone looking for the rememberme().key() feature in the future, it seems that as of Spring Boot 2.2.6 there is SecureRandom generator to generate the key if it is not provided. Here is the implementation found in org.springframework.security.config.http.AuthenticationConfigBuilder.createRememberMeFilter
private String createKey() {
SecureRandom random = new SecureRandom();
return Long.toString(random.nextLong());
}

Related

How to programmatically invalidate a Quarkus Cache?

I´m running into a problem where using the #CacheInvalidate annotation is not enough anymore.
One method has to erase two different caches, one of them uses two of the given arguments and the other uses all three.
#CacheInvalidate(cacheName = "cache-with-two-identifiers")
#CacheInvalidate(cacheName = "cache-with-three-identifiers")
public void doSomething(#CacheKey String identifier, #CacheKey String anotherIdentifier, String aThirdIdentifier){
}
The #CacheKey annotated arguments are used for the cache with two identifiers, so I cannot annotate the third argument as well, but it would be required to match the keys of the cache-with-three-identifiers.
The only solution I see so far is programmatically clearing the third-arg-cache within the method itself. How would you do that in Quarkus?
There is currently no programmatic caching API for Quarkus.
There is already an open issue for it, you can +1 for it and provides feedback: https://github.com/quarkusio/quarkus/issues/8140

Spring Cache+Redis cache doesn't calculate keys based on method/class names

I'm using redisson with a jcache abstraction, simply put I have this:
public class MyService{
#Cacheable("cacheA")
public String returnSomethingAfterLongTime(String parameter){
//...
}
#Cacheable("cacheA")
public String returnSomethingElse(String parameter){
}
}
Problem is that both of them create a redis key like "cacheA::parameter", in other words the class and method name are not taken into account.
This causes a problem if the string "parameter" is a common word because I have to be aware of every part of code where "cacheA" is used so to make sure that no inefficiency is brought up due to the fact that the "parameter" key could be replicated among calls.
Is there something that I'm doing wrong?
It looks like you can specify a "key" attribute to customize it to cache based on method name.
Spring Cacheable key attribute
There are a lot of good examples and answers on this post.
I've never personally used Spring Cache, but it looks like you can specify #Cacheable("cacheA", key="#parameter") and the value of parameter will be used as the key rather than the word "parameter".

How can I pre-generate a BCrypt hashed password for my Spring Boot application?

I have a Spring Boot application (code here) with a security configuration that utilizes a BCryptPasswordEncoder:
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
I'd like to pre-generate a couple of passwords to initialize my database, for testing or for logging in on a developer machine. (Not for production.) My database is PostgreSQL and the schema is based on the Spring Security default schema, with a users table and an authorities table. My SQL statement looks like this:
insert into users (username, password, enabled) values ('joe','$2y$12$XodbOuISPCPQijlY8MIRUepDeURhxDe09/4VQU0Cno5zkTEKjZouO',true);
I don't know much about how the BCrypt hashing algorithm works, but I generated this password hash (for the password "test") using a free online BCrypt hash generator that looks legitimate. Nevertheless, I cannot log in to my Spring Boot application. The error in the logs is "bad credentials". What gives?
PS: This is a follow-up to this other question.
You can use online BCrypt generator but the thing is that the online generator might generate different regex from your Spring Segurity enconder.
For example the online generator can generate BCrypt with regex “$2y” and your Spring Boot enconder generate with “$2a” regex. If this happen you will get always bad credencials.
I strongly recommend you to generate your passwords using Spring Boot BCrypt Enconder.
#SpringBootApplication
public class QuartzJdbcJobStoreBciApplication extends SpringBootServletInitializer{
public static void main(String[] args {
SpringApplication.run(QuartzJdbcJobStoreBciApplication.class, args);
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String password [] = {"Password1", "Password2", "Password3"};
for(int i = 0; i < password.length; i++)
System.out.println(passwordEncoder.encode(password[i]));
}
}
The problem turned out to be the prefix $2y in the hash. This is supposed to represent a version of the BCrypt algorithm but, according to Wikipedia, the prefix is not standard. To be clear, that online generator isn't using a non-standard algorithm, just a non-standard label.
Incidentally, the next section of the hash, $12, indicates the number of rounds of hashing, and even though it's not the same as the Spring default (10 rounds), it doesn't cause the problem.
The solution is to simply change the y for an a. $2a is the standard prefix for a BCrypt hash. You don't need to find a different BCrypt generator or anything, just edit the string.
This works:
insert into users (username, password, enabled) values ('joe','$2a$12$XodbOuISPCPQijlY8MIRUepDeURhxDe09/4VQU0Cno5zkTEKjZouO',true);

Spring RedisTemplate : use same key with multiple RedisTemplate to store different values

I am new to Redis and want to implement it with my existing spring application.
My question is to use different redisTemplate with same keys to store different types of values.
For e.g.
I have redisTemplate1 and redisTemplate2 beans defined in spring, like.
<bean id="redisTemplate1" class ="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref ="connectionFactory" />
<bean id="redisTemplate2" class ="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref ="connectionFactory" />
In java file to my service, I have created two different data structure using these two redis templates.
#Autowired
#Qualifier(value = "redisTemplate1")
private RedisTemplate<String, Student> redisTemplate1;
#Autowired
#Qualifier(value = "redisTemplate2")
private RedisTemplate<String, Address> redisTemplate2;
And, using following pattern to store data.
redisTemplate1.opsForHash().put("KEY1", student.getId(), student);
redisTemplate2.opsForHash().put("KEY1", address.getId(), address);
The case is, I have primary keys starting with 1 for each table. So 1 is there a primary key of Student as well as of Address.
I am using line below to get Student back from data-store.
(Student) redisTemplate1.opsForHash().get("KEY1", 1);
But, unfortunately it generates an exception.
java.lang.ClassCastException: com.redis.model.Address cannot be cast to com.redis.model.Student
So, my questions are,
Is it possible to use multiple redis templates ?
If yes, can I use same key (unique for each template) to store different types of data and access the same data stored using that template and key ?
If not, what are the alternative to perform same operation ?
Thanks in advance.
Actually Redis is a key/value store and if you use the same key for the same store you just override the old value with new one. And it doesn't matter how much RedisTemplates (or even connectionFactorys) you have, if the real Redis server is the same.
Now how to help you with your task:
You should have different kyes for different domain objects: e.g. students, addresses.
Since you are going to store domain objects with their own keys it looks like Map value is for you. I mean under key students a map of Students should be stored ,and the same for Addresses.
However you, actually, do it, but you use the same key for both domains.
So, the answer for you: that's because you are using the same Redis from both RedisTemplates.

Best practice for validating a URL with Spring-MVC?

I am using Spring MVC for my web application.
I need to validate that the URL the user inputs is valid and was wondering if there is something in Spring that can do the basic checks for me (for example starts with http/https, has domain name etc).
ValidationUtils only contains very basic checks and I know I can write a regular expression in the validate() method however prefer to avoid it inm case someone has already done it :)
Thanks
In the past, I have always utilized Hibernate Validator. Simply annotate the appropriate field in your form bean with a #URL constraint.
If you've never used the ORM part of Hibernate before, don't let that scare you. The Validator portion is not dependent on the ORM stuff, and integrating it into Spring is very straightforward.
If for some reason you can't use Hibernate Validator... or you just want to stick with what you're comfortable with, a good place for regex's is RegExLib.com; several patterns that can match a URI are listed there.
Ended up using UrlValidator from apache commons.
I know this question is quite old, but I just need the same and I think I'll go with the PropertyEditors in SpringFramework.
More precisely there is URLEditor, which you can use to convert a String representation to an actual URL object.
Here is a link to the respective documentation:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-beans-conversion
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/propertyeditors/URLEditor.html
In my case, I think about using the following code within a Spring Validator to check whether a String entered by a user is a valid URL or not:
try {
PropertyEditor urlEditor = new URLEditor();
urlEditor.setAsText(field.getValue());
} catch (IllegalArgumentException ex) {
errors.rejectValue("nameOfTheFieldToBeValidated", "url_is_invalid");
}
However, as for now, I'm unsure whether it is possible to configure which protocol is going to be accepted as valid (i.e. URLEditor seems to also accept URLs starting with "classpath:")
Use a spring interceptor:
http://java.dzone.com/articles/using-spring-interceptors-your

Resources