DelegatingPasswordEncoder adding prefix to encoded password which is resulting in auth failure - spring-security

#Override
public boolean matches(CharSequence rawPassword, String prefixEncodedPassword) {
//rawPassword: "12345\n" //prefixEncodedPassword: "12345\n\n"
if (rawPassword == null && prefixEncodedPassword == null) { return true; }
String id = extractId(prefixEncodedPassword); //prefixEncodedPassword: "12345\n\n"
PasswordEncoder delegate = this.idToPasswordEncoder.get(id);
if (delegate == null) {
return this.defaultPasswordEncoderForMatches.matches(rawPassword, prefixEncodedPassword);
}
String encodedPassword = extractEncodedPassword(prefixEncodedPassword);
return delegate.matches(rawPassword, encodedPassword);
}
As is above picture, byte value representation of password differs which is causing auth failure I see.
#Bean
public UserDetailsManager userDetailsService(DataSource dataSource) {
return new JdbcUserDetailsManager(dataSource);
}
I am using default JdbcUserDetailsManager impl. {noop} encoder is used.
When equality test happens on value, matches test fails. Also I did a manual entry of password in the 'users' table, which should be taken as encoded password while performing test. But what is this prefix "\n" being added? Is that the reason bytecode value is differing? I am new to this and learning. Should I perform any other test here?

Related

Neo4j SDN - OGM nodes equality

I have a problem with Spring Data Neo4j and OGM. When I create a node for first time, it`s ok but if I refresh that page I get this error:
Cypher execution failed with code 'Neo.ClientError.Schema.ConstraintValidationFailed': Node(126) already exists with label Country and property name = 'Country-1'.
I searched the web and read so many documents about equals and hashCode but none of them is helping. Here are my classes:
public abstract class Place {
#Id
#GeneratedValue(strategy = UuidStrategy.class)
private String id ;
private String name ;
public String getId(){return id ;}
}
#Getter
#Setter
#NodeEntity(label = "Country")
#CompositeIndex(unique = true , properties = "name")
public class Country extends Place {
private String label = "Country";
public Country() {}
#Override
public int hashCode() {
int result = label == null ? 1 : label.hashCode();
result = 31 * result + this.getName() == null ? 0 : this.getName().hashCode();
result = 31 * result + this.getId() == null ? 0 : this.getId().hashCode();
return result;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Country)) {
return false;
}
Country that = (Country) o ;
return this.getName().equals(that.getName())
&& this.getId().equals(that.getId())
&& this.getLabel().equals(that.getLabel());
}
}
Repository is default. As I know it`s a problem of equality check but how can I fix this?
You created a constraint on your Country entity by defining
#CompositeIndex(unique = true , properties = "name")
and probably you also enabled the auto index manager feature in the Neo4j-OGM SessionFactory configuration.
This is not related to any implementation of hashCode or equals.
This will also explain the behaviour you are facing: First run succeeds but the very same action repeated failed.

Do not ask login for rememberMe users in checkout process etc. in SAP Hybris

When I make rememberMe(spring security) active in Hybris, I want rememberMe users to behave like Hard Login users. I mean, I would like those rememberMe users (soft login) to not face any obstacle like when they want to proceed in the checkout process or something like that. How can I achieve this in SAP Hybris platform?
Your question: How to disable HardLogin for the remember-me user in Hybris?
find the detail explanation here
Change RequireHardLoginBeforeControllerHandler
Change beforeController method of RequireHardLoginBeforeControllerHandler.java, so that it always check if remember-me cookies present in the request and guid is missing or invalidated then create new guid without redirecting login page.
Below yourstorefrontRememberMe needs to change with your storefront name, like mySiteRemmberMe
public static final String SECURE_REMEMBER_ME_COOKIES = "yourstorefrontRememberMe";
#Resource(name = "guidCookieStrategy")
private GUIDCookieStrategy guidCookieStrategy;
#Override
public boolean beforeController(final HttpServletRequest request, final HttpServletResponse response,
final HandlerMethod handler) throws Exception
{
boolean redirect = true;
// We only care if the request is secure
if (request.isSecure())
{
// Check if the handler has our annotation
final RequireHardLogIn annotation = findAnnotation(handler, RequireHardLogIn.class);
if (annotation != null)
{
final String guid = (String) request.getSession().getAttribute(SECURE_GUID_SESSION_KEY);
if ((!getUserService().isAnonymousUser(getUserService().getCurrentUser()) || checkForAnonymousCheckout()) &&
checkForGUIDCookie(request, response, guid))
{
redirect = false;
}
if (redirect)
{
if(isRememberMeCookiePresent(request))
{
// If you find your guid is missing, lets recreate it.
guidCookieStrategy.setCookie(request, response);
return true;
}
else
{
LOG.warn((guid == null ? "missing secure token in session" : "no matching guid cookie") + ", redirecting");
getRedirectStrategy().sendRedirect(request, response, getRedirectUrl(request));
return false;
}
}
}
}
return true;
}
protected boolean isRememberMeCookiePresent(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if ((cookies == null) || (cookies.length == 0)) {
return false;
}
for (Cookie cookie : cookies) {
if (SECURE_REMEMBER_ME_COOKIES.equals(cookie.getName())) {
return cookie.getValue() != null;
}
}
return false;
}

ModelState.IsValid is false when I have a nullable parameter

I reproduced the issue I am having in a brand new MVC Web API project.
This is the default code with a slight modification.
public string Get(int? id, int? something = null)
{
var isValid = ModelState.IsValid;
return "value";
}
If you go to http://localhost/api/values/5?something=123 then this works fine, and isValid is true.
If you go to http://localhost/api/values/5?something= then isValid is false.
The issue I am having is that if you provide a null or omitted value for an item that is nullable, the ModelState.IsValid flags a validation error saying "A value is required but was not present in the request."
The ModelState dictionary also looks like this:
with two entries for something, one nullable, which I am not sure if it is significant or not.
Any idea how I can fix this so that the model is valid when nullable parameters are omitted or provided as null? I am using model validation within my web api and it breaks it if every method with a nullable parameter generates model errors.
It appears that the default binding model doesn't fully understand nullable types. As seen in the question, it gives three parameter errors rather than the expected two.
You can get around this with a custom nullable model binder:
Model Binder
public class NullableIntModelBinder : IModelBinder
{
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(int?))
{
return false;
}
ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (val == null)
{
return false;
}
string rawvalue = val.RawValue as string;
// Not supplied : /test/5
if (rawvalue == null)
{
bindingContext.Model = null;
return true;
}
// Provided but with no value : /test/5?something=
if (rawvalue == string.Empty)
{
bindingContext.Model = null;
return true;
}
// Provided with a value : /test/5?something=1
int result;
if (int.TryParse(rawvalue, out result))
{
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Cannot convert value to int");
return false;
}
}
Usage
public ModelStateDictionary Get(
int? id,
[ModelBinder(typeof(NullableIntModelBinder))]int? something = null)
{
var isValid = ModelState.IsValid;
return ModelState;
}
Adapted from the asp.net page: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api for further reading and an alternative method to set it at the class(controller) level rather than per parameter.
This handles the 3 valid scenarios:
/test/5
/test/5?something=
/test/5?something=2
this first give "something" as null. Anything else (eg ?something=x) gives an error.
If you change the signature to
int? somthing
(ie remove = null) then you must explicitly provide the parameter, ie /test/5 will not be a valid route unless you tweak your routes as well.
You'll have to register a custom model-binder for nullable types as the default binder is calling the validator for nullable parameters as well, and the latter considers those empty values as invalid.
The Model Binder:
public class NullableModelBinder<T> : System.Web.Http.ModelBinding.IModelBinder where T : struct
{
private static readonly TypeConverter converter = TypeDescriptor.GetConverter( typeof( T ) );
public bool BindModel( HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext )
{
var val = bindingContext.ValueProvider.GetValue( bindingContext.ModelName );
// Cast value to string but when it fails we must not suppress the validation
if ( !( val?.RawValue is string rawVal ) ) return false;
// If the string contains a valid value we can convert it and complete the binding
if ( converter.IsValid( rawVal ) )
{
bindingContext.Model = converter.ConvertFromString( rawVal );
return true;
}
// If the string does contain data it cannot be nullable T and we must not suppress this error
if ( !string.IsNullOrWhiteSpace( rawVal ) ) return false;
// String is empty and allowed due to it being a nullable type
bindingContext.ValidationNode.SuppressValidation = true;
return false;
}
}
Registration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ...
var provider = new SimpleModelBinderProvider(typeof(int?), new NullableModelBinder<int>());
config.Services.Insert(typeof(ModelBinderProvider), 0, provider);
// ...
}
}
Remove the default null value from the second parameter. The model binder will set it to null if it's something other than int.
I've found a working workaround for me (just exclude null values from data being sent - as opposed to sending values as nulls).
See https://stackoverflow.com/a/66712465/908608

Implicit declarations

I'm trying to create a grammar, using implicit declarations. After reading the a forum entry (http://www.eclipse.org/forums/index.php?t=msg&S=2e4a29d7fff0322e71b35e3a3aa63e3f&th=198813&goto=634090#msg_634090) I wrote my own LinkingService:
public class OntMLLinkingService extends DefaultLinkingService {
private final Map<Rule, Resource> implicitVariables = new HashMap<>();
public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException {
List<EObject> linking = super.getLinkedObjects(context, ref, node);
if (!linking.isEmpty())
return linking;
if (context instanceof VariableReference && ref.equals(OntMLPackage.eINSTANCE.getVariableReference_Variable())) {
// Find the rule, the references is used in
EObject container = context.eContainer();
while (!(container instanceof Rule))
container = container.eContainer();
Rule rule = (Rule) container;
// Check, if a resource was already created for the rule
Resource res = implicitVariables.get(rule);
if (res == null) {
// Create and register new resource
res =
rule.eResource().getResourceSet()
.createResource(URI.createURI("http://wwwcs.vs.hs-rm.de/OntML/Variable/" + UUID.randomUUID()));
implicitVariables.put(rule, res);
}
// Get the cross ref string
final String crossRefString = getCrossRefNodeAsString(node);
if (crossRefString != null && !crossRefString.equals("")) {
// Search for the variable in the resource
Optional<Variable> existingVar =
res.getContents().stream().map(eobj -> (Variable) eobj).filter(var -> var.getName().equals(crossRefString))
.findAny();
if (!existingVar.isPresent()) {
// Create and register new variable, if the variable does not exist yet
Variable newvar = OntMLFactory.eINSTANCE.createVariable();
newvar.setName(crossRefString);
res.getContents().add(newvar);
}
}
// Add all contents of the resource to the linked objects
linking.addAll(res.getContents());
}
return linking;
}
}
I've debugged the "getLinkedObjects" method and everything seems to work fine, but my editor won't show errors anymore, even though I write invalid code and my compiler gets a null pointer, when invoking the "getName" method of any "Variable". I think it's a problem with the LazyLinker and EMF proxies.

ConversionErrorInterceptor throws conversion error during quit/cancel (Struts 2)

The scenario of the problem is this
1) We map the struts field values to the dtos. The dtos contain integer fields which again are displayed on the screen.
2) Now I enter an incorrect value which gives conversion error for that integer field.
3) At that point in time I decide to quit the page(i.e press cancel), I get a conversion error. This is because the StrutsConversionErrorInterceptor gets called everytime.
Is there any way that I can skip the strutsConversionErrorInterceptor when I am calling a particular method the way we can skip validation using excludeMethods
Use this code to override Struts's StrutsConversionErrorInterceptor...
public class MyConversionErrorInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
public static final String ORIGINAL_PROPERTY_OVERRIDE = "original.property.override";
protected Object getOverrideExpr(ActionInvocation invocation, Object value) {
ValueStack stack = invocation.getStack();
try {
stack.push(value);
return "'" + stack.findValue("top", String.class) + "'";
} finally {
stack.pop();
}
}
#Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext invocationContext = invocation.getInvocationContext();
Map<String, Object> conversionErrors = invocationContext.getConversionErrors();
ValueStack stack = invocationContext.getValueStack();
HashMap<Object, Object> fakie = null;
BaseAction baseAction = (BaseAction) invocation.getAction();
String buttonName = baseAction.getButtonName();
for (Map.Entry<String, Object> entry : conversionErrors.entrySet()) {
String propertyName = entry.getKey();
Object value = entry.getValue();
if (shouldAddError(propertyName, value)) {
String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
ValidationAware va = (ValidationAware) action;
if(buttonName.equalsIgnoreCas("Next")){
va.addFieldError(propertyName, message);
}
}
if (fakie == null) {
fakie = new HashMap<Object, Object>();
}
if(buttonName.equalsIgnoreCas("Next")){
fakie.put(propertyName, getOverrideExpr(invocation, value));
}
}
}
if (fakie != null) {
// if there were some errors, put the original (fake) values in
// place right before the result
stack.getContext().put(ORIGINAL_PROPERTY_OVERRIDE, fakie);
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation, String resultCode) {
Map<Object, Object> fakie = (Map<Object, Object>) invocation.getInvocationContext().get(ORIGINAL_PROPERTY_OVERRIDE);
if (fakie != null) {
invocation.getStack().setExprOverrides(fakie);
}
}
});
}
return invocation.invoke();
}
protected boolean shouldAddError(String propertyName, Object value) {
if (value == null) {
return false;
}
if ("".equals(value)) {
return false;
}
if (value instanceof String[]) {
String[] array = (String[]) value;
if (array.length == 0) {
return false;
}
if (array.length > 1) {
return true;
}
String str = array[0];
if ("".equals(str)) {
return false;
}
}
return true;
}
}
You can specify you button names on which you want validation to fire. In above code I have used "Next" in code you can see
if(buttonName.equalsIgnoreCas("Next"))
Yes, you can skip calling the interceptor.
Just remove the interceptor definition from your action definition in struts.xml file.
i.e., remove <interceptor-ref name="conversionError"/>
Mainly this interceptor adds any error found in the ActionContext's conversionErrors map as a field error (provided that the action implements ValidationAware). In addition, any field that contains a validation error has its original value saved such that any subsequent requests for that value return the original value rather than the value in the action. This is important because if the value "abc" is submitted and can't be converted to an int, we want to display the original string ("abc") again rather than the int value (likely 0, which would make very little sense to the user).
After you removed this interceptor, if the struts failed to map the field with parameter of the object(i.e., from string to int), it throws result input action error.
This seems to be a better method to handle this scenario - using Conversion Validator. Repopulating Field upon conversion Error section is something very useful:
http://struts.apache.org/2.0.14/docs/conversion-validator.html

Resources