I know I ran across a post at some point, but I can't seem to find anything. It seems that by default, ServiceStack allows access to /auth via GET or POST. GET is not something we want in production.
I need to turn off GET access to /auth. Any ideas?
You can use the AuthenticateServices custom ValidateFn to add your own custom validation, e.g:
AuthenticateService.ValidateFn = (authService, verb, requestDto) => {
if (verb == HttpMethods.Get)
throw new NotSupportedException("GET's not allowed");
};
Otherwise you can add your own Restricting Services Attributes on services you don't own by using the fluent API for dynamically adding attributes, e.g:
typeof(Authenticate)
.AddAttributes(new RestrictAttribute(RequestAttributes.HttpPost));
Related
I am attempting to discover which extension properties I have available to my application. I originally followed this guide to get the extension attributes:
https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/#use-custom-attributes
But that just returns the following JSON:
{
"odata.metadata": "https://graph.windows.net/screenmediatestb2c.onmicrosoft.com/$metadata#directoryObjects/Microsoft.DirectoryServices.ExtensionProperty",
"value": []
}
I have also attempted to do this with regular HTTP requests using Postman, but with the exact same result. I can authenticate and load applications, users, groups etc. But it doesn't return any of my custom attributes, of which I have 2.
The endpoint I am using is:
https://graph.windows.net/[tenant]/applications/[application object ID]/extensionProperties?api-version=1.6
Does anyone have any idea what I am doing wrong?
I just noticed a disclaimer at the bottom of this page https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-reference-custom-attr/. Looks like this might be our problem.
There is a known limitation of custom attributes. It is only created
the first time it is used in any policy, and not when you add it to
the list of User attributes.
There is a bug in the accompanying GitHub repo for the tutorial at:
https://azure.microsoft.com/en-us/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/#use-custom-attributes
Un-bust your balls by changing Program.GetB2CExtensionApplication(...) to:
private static void GetB2CExtensionApplication(string[] args)
{
object formatted = JsonConvert.DeserializeObject(client.
GetApplications("$filter=startswith(displayName, 'b2c-extensions-app')").Result);
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(JsonConvert.SerializeObject(formatted, Formatting.Indented));
}
Instead of checking if the displayName equals 'b2c-extensions-app' it checks if it starts with 'b2c-extensions-app'. They have changed the name of the application in later versions of Azure AD B2C.
When you use the returned ID to get your extensions you will see that the Custom Attribute Name is prefixed with a Guid, and that's why we're been having trouble accessing it:
Eg. extension_10ecdccd92c446829a399e68ed758978_MyCustomAttribute
The correct GET URL for the Get-B2C-Application should be:
GET https://graph.windows.net/{Tenant}/applications?api-version=1.6&$filter=startswith(displayName,'b2c-extensions-app')
And the GET URL for the Extensions Properties (Custom Atttributes) should be:
GET https://graph.windows.net/{Tenant}/applications/{ObjectID}/extensionProperties?api-version=1.6
It's possible to get the attributes via LINQ:
string selectClause = "GivenName,Surname,Id,Mail"
+ ",extension_{ExtensionPropertyPrefixGUID}_myAttribute1"
+ ",extension_{ExtensionPropertyPrefixGUID}_myAttribute2";
var result = await _graphClient.Users
.Request()
.Select(selectClause)
.GetAsync();
The extension attributes will then be accessible via the AdditionalData
foreach (User user in result.CurrentPage)
{
string attribute1Value = (string)user.AdditionalData["extension_{ExtensionPropertyPrefixGUID}_myAttribute1";
}
I wanted to block some users for accessing some services in JHipster.
How can I authorize a particular user for accession a ReST web Service in JHipster?
For blocking the access on the backend side, use the #Secured annotation on selected methods (rest entry points) in web/rest/*resource.java.
Example:
#RequestMapping(value = "/data-fields",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
#Secured({AuthoritiesConstants.ADMIN})
public List<DataFieldDTO> getAllDataFields() {
log.debug("REST request to get all DataFields");
return dataFieldService.findAll();
}
As Gaël Marziou says, I believe that what you are trying to do is to block it on frontend's part. If it´s the case a possible way to do it is managing the use of "has-authority". For example: has-authority="ROLE_ADMIN"
So what you should do is the opposite, create an authority which allows some users to have access to ReST web Service
use has-authority and put your expected authority it will work 100% . tasted
write it on your html tag has-authority="ROLE_ADMIN" or your expected user
On /config/SecurityConfiguration.java
You can change access of the api that you want like
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/auth/*").hasAnyAuthority("ADMIN", "USER")
Or you can use auth.inMemoryAuthentication()
for more information read link below:
https://www.baeldung.com/spring-security-expressions
I use the security.yml with access_control to secure the API paths based on the user role. This works fine, but how do I secure specific parameters like /api/project/:id?
Different users have access to different project ids. Therefore a database call has to be made to check if this user has access to this project.
I tried to use $this->denyAccessUnlessGranted('GET', $projectId, 'Unauthorized access!'); in the ProjectController, which calls a custom Voter to check the database and therefore the access.
public function getProjectAction(Request $request, $id)
{
$this->denyAccessUnlessGranted('GET', $id, 'Unauthorized access!');
This works, but it seems very unpractical to add this code to 10+ actions in the ProjectController alone and also in many parts of the API.
Therefore my question: What is the best pratice to secure a REST api with symfony2, fosUserBundle and fosRestBundle
I would suggest introducing security voters.
http://symfony.com/doc/current/cookbook/security/voters_data_permission.html
Also create some kind of exception handler / listener, to catch your exceptions and make a specific error response.
http://symfony.com/doc/current/cookbook/service_container/event_listener.html
I have ServiceStack v4 service but when I call the auth/logout route (using either POST or GET) to logout the currently logged-in user, I get an error:
400 Not Empty
User Name cannot be empty
Password Cannot be empty
As I wouldn't expect users to enter credentials when logging out, I am surely missing something?
I have the AuthFeature registered during host initialisation, and I am using CredentialsAuthProvider. I have taken the code from Github so I can see how it works.
My Client Code:
var rest = Restangular.one('auth/logout').get();
//var result = rest.post({userName: userName});
this.requestTracker.addPromise(rest);
return rest;
After a lot of digging, this happens when you are using CredentialsAuthProvider. Within this class, a validator is defined that validates all instances of the Authenticate request. As the logout route uses the Authenticate request, this validator is fired.
I got round it by modifying the validator to:
RuleFor(x => x.UserName).NotEmpty().When(d => d.provider != "logout");
RuleFor(x => x.Password).NotEmpty().When(d => d.provider != "logout");
This is probably not the most elegant way of fixing long term, but got me up and running.
I know this question is old, but I recently have been struggling with the same thing. What occurs is that before the Authenticate.Post function is called, the validation cache is checked and the CredentialsAuthProvider which has the mentioned validator fails unless username and password are not empty.
Now, i'm not sure if it makes a difference if you only have that provider enabled or not - I've not tested. I actually have my own custom provider that subclasses CredentialsAuthProvider and it's the only one I register.
The only way currently is to either pass a non-empty (but useless) password and username, or modify your own custom provider, overriding the Authenticate function and using a modified version of the validator as mentioned above.
In my previous project, I use a framework (Agatha RRSL) similar to ServiceStack, in that everything is made of Request, Response and Handler. It also has Interceptors that can attach to handler and you can inject other interfaces to the handler as well. I can use this to open a transaction BeforeHandling, access to both request and response in AfterHandling, create audit, save to database and close transaction if needed.
I try to experiment similar with SerivceStack. But seems with Filters, I can't grab request and response together?
With custom ServiceRunner. When I try to debug OnAfterExecute(...), I can see the name of my request dto in IRequestContext {ServiceStack.ServiceHost.HttpRequestContext}. But just the name, I couldn't figure out how to retrieve the actual request object to work with the response object.
Another thing I haven't figure out is if it's possible to inject the auto wired service interface into it, like a db context or audit service. Maybe this one is too far ahead in the pipeline?
The final thing is, it seems I can only register one custom service runner? With Interceptor, I can drop a bunch of them, and they will wrap around each other.
Any thoughts? Thanks
The RequestContext also contains the HttpRequest and HttpResponse which you can get access with:
var httpReq = RequestContext.Get<IHttpRequest>();
var httpRes = RequestContext.Get<IHttpResponse>();
See the docs on Accessing HTTP Specific features for more info.