I'm writing some tests with the codeception REST module.
The project I'm working on is in the early stages and we haven't implemented token-based authentication yet; so for now the authentication is done via a REST API but it uses $_SESSION for persistence.
To test authenticated requests I need to keep the PHPSESSID cookie and send it with every request. Is there a way to read/set cookies when working with the REST module?
Ok I got the solution. My suite name is api, so codeception generated a file at tests/_support/Helper/Api.php. Before making changes here, I had to edit my suite YAML file api.suite.yml to enable the helper. My YAML file looks like this:
class_name: ApiTester
modules:
enabled:
- REST:
depends: PhpBrowser
url: https://website.com/api/
part: Json
- \Helper\Api
Now that the file is enabled, run codecept build so that it updates the generated files to read your helper.
In the Api helper class, I added two methods:
public function capturePHPSESSID()
{
$cookie = $this->getClient()->getCookieJar()->get('PHPSESSID');
echo "Cookie: ", $cookie;
}
/**
* #return \Symfony\Component\HttpKernel\Client|\Symfony\Component\BrowserKit\Client $client
*/
protected function getClient()
{
return $this->getModule('REST')->client;
}
This is all that you need to read the PHPSESSID cookie! Feel free to capture it so you can then write a method to re-use it by setting calling $this->getClient()->getCookieJar()->set(....)
Related
I am want to build an app which has a static frontend ( target: 'static' in nuxt.config.js ), and a backend using ktor. The app will need to authenticate users but I do not want to manage passwords and things myself, so I would like to integrate with AWS Cognito. Based on my understanding, I think this is the workflow I want:
User is browsing the site anonymously (no login)
They do some action which requires login or explicitly click on login button.
User gets redirected to AWS Cognito ui for login. They may register for new account, login with their existing, or login using another provider (after configuring cognito for it).
Cognito ui redirects user back to the app ui but with JWT tokens in query params (I think this is just how cognito does it)
The JWT token (s?) get stored in vuex store / nuxt auth
The token is used when making requests to the backend. As well as showing some additional components / actions if the user is authenticated and their basic info like username (part of jwt?)
I think I have cognito and the ktor backend setup correctly but I don't know how to get started for the frontend.
The nuxt auth module guide says to set up middleware, but afaik middleware is only for server side rendered apps.
I need to activate the vuex store but I don't know what to put there. Are there some specific things the auth module expects or do I just create an empty file in the directory?
How do I tell it when to redirect or read the token from query param?
How to parse the JWT token (if it doesn't automatically) and get some payload info like username from it?
Does the axios module get configured automatically to make use of this?
I found this old github issue 195 in the auth module repo, but I believe that's for when the "login form"/ui is part of the nuxt app and client is making use of the cognito api without 'redirect'.
Unfortunately everything in this stack is new for me so any help is appreciated. If there is already a project doing something similar, I look at the code and try to figure it out but right now I'm lost.
update 2020-12-31, mainly so that I can put a bounty on this soon: The live demo at https://auth0.nuxtjs.org/ seems to be doing what i'm looking for but then the github page read me shows something else https://github.com/nuxt/example-auth0. Also i don't see middleware / plugins used anywhere. it's all mostly configured through nuxt config, so it only works for the auth0 custom provider?
I was having the same issue as you:
How do I tell it when to redirect or read the token from query param?
I solved this by configuring auth.redirect.callback to match the endpoint that cognito will callback with the token. I believe this will tell the middleware when to look for a new token in the query param.
nuxt.config.js:
auth: {
redirect: {
callback: '/signin',
...
},
strategies: {
awsCognito: {
redirectUri: "http://localhost:8080/signin",
...
}
}
}
And to answer your other questions:
The nuxt auth module guide says to set up middleware, but afaik middleware is only for server side rendered apps.
I tried this setup with ssr: false and it still works fine.
I need to activate the vuex store but I don't know what to put there. Are there some specific things the auth module expects or do I just create an empty file in the directory?
An empty index.js file is fine.
How do I tell it when to redirect or read the token from query param?
See first answer above.
How to parse the JWT token (if it doesn't automatically) and get some payload info like username from it?
From my initial testing I found that the middleware will automatically call the userInfo endpoint when user data is requested e.g. this.$auth.user.email
strategies: {
awsCognito: {
scheme: "oauth2",
endpoints: {
userInfo: "https://x.amazoncognito.com/oauth2/userInfo",
ref: https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html
Does the axios module get configured automatically to make use of this?
Yes.
We have the requirement in our enterprise environment to serve static file content from a network share in our ASP.NET Core application. Basically, it gets served under some sub path /content. For this, we have the following code, which works fine:
app.UseFileServer(new FileServerOptions
{
FileProvider = new PhysicalFileProvider("//our/network/share"),
RequestPath = new PathString("/content"),
EnableDirectoryBrowsing = false
});
Now in production the system user under whose context the web application is hosted has no access to the file share. Thus, we have to use a certain technical domain user to access the files and for this we have to provide credentials (username/password) of this system user to the file server.
Unfortunately, we did not find an option to provide credentials to UseFileServer(). Is it anyway possible?
According to the documentation for UseFileServer it combines the functionality of among other things UseStaticFiles. According to the middleware documentation, the static file module provides no auth checks. They do give you some options on how to accomplish file serving with authorization (again from the middleware docs):
If you want to serve files based on authorization:
Store them outside of wwwroot and any directory accessible to the static file middleware.
Deliver them through a controller action, returning a FileResult where authorization is applied.
Not sure how you are going to pass the username/password to the server. If you plan to use something like basic authentication (and don't want to use the methods outlined above), you can probably modify the headers (when serving the static files) to accomplish the desired effect, but that is a workaround and probably not a good idea.
I would use middleware to protect contents. I will try to write simple example(I assumed you are using any authentication middleware to authenticate your users and my example is for static files).
-- Below code is untested and is just for an illustration--
First, you need to create a middleware something like this:
public class ProtectFileMiddleware
{
private readonly RequestDelegate _next;
public ProtectFileMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Path.StartsWithSegments("/protected"))
{
if (!context.User.IsInRole("Admin"))
{
await context.Authentication.ChallengeAsync();
return;
}
}
await _next(context);
}
}
and use this middleware like below:
public void Configure(IApplicationBuilder app)
{
app.Use(?)Authentication();// it depends on your design
app.UseMiddleware<ProtectFileMiddleware>();
app.UseStaticFiles();
// other
}
Result: if you try to access /protected url as an admin user, you will get expected response otherwise you will take a 401/403 response.
For more flexible way take a look at http://odetocode.com/blogs/scott/archive/2015/10/06/authorization-policies-and-middleware-in-asp-net-5.aspx
Yeah, those answers assume you're asking about client credentials. What you really need is a IFileProvider implementation that has credentials to access a specific resource. I don't know that .NET is very good at accessing files as different users, it usually relies on impersonation. See How to present credentials in order to open file?
Has anybody managed to successfully combine Google authentication with Burt Beckwith's awesome Grails-based Spring Security plugin recently? I wanted to go down that path with Grails 2.4.3, and after some fooling around (and recompiling the donbeave version of the plugin at https://github.com/donbeave/grails-spring-security-oauth-google) I was able to find a combination of references that would compile and run together. I ended up adding the following lines to my BuildConfig.groovy:
compile ':spring-security-core:2.0-RC4'
compile ":spring-security-oauth:2.1.0-RC4"
compile ':spring-security-oauth-google:0.3.1'
I found, however, that the changes created by the initialization command “grails s2-init-oauth” don’t give me all the modifications that I need in order to move forward. I ended up adding a block to my config.groovy that looked like this:
oauth {
providers {
google {
api = org.grails.plugin.springsecurity.oauth.GoogleApi20
key = 'MY KEY'
secret = 'MY SECRET'
successUri = '/oauth/google/success'
failureUri = '/oauth/google/error'
callback = "${baseURL}/oauth/google/callback"
scope = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email'
}
}
}
These config definitions specify a callback in my code (referred to above as ./oauth/google/callback) which didn’t exist. After I brought in a controller from the recommended example (https://github.com/bagage/grails-google-authentification-example), substituted "/springSecurityOAuth/onSuccess" for "/oauth/google/callback", (and registered by redirect URL through the Google Developers Console) I found that my onSuccess method was indeed being called, but the data structures referenced in the controller were wrong, and it seemed as if I would need to largely rewrite the controller logic in order to get everything working. I have to assume that other people want to accomplish Google-based authentication in the same way that I do. Is there an complete operational example somewhere? Or can someone tell me where I’ve gone wrong in my attempt to utilize the standard plug-ins? Thanks for any assistance.
You need to use spring security oauth plugin also. Please refer here https://github.com/cazacugmihai/grails-spring-security-oauth,
When you click on button, it hits the authenticate action inside Oauth controller which gets
authentication()
url of the google. After successful authentication, it hits callback() action Of Oauth controller which then redirects to onSuccess() action of SpringSecurityOauthController which then saves the info to OAuthId domain and finally redirects to the successUri given in config.
I understand there is more than one way of handling service authentication/authorization, but I cannot make it work for static files.
Is there a way of configuring the behavior to be the same as with services; if not authenticated a request to index.html should redirect to login page the same as a request to secured dto/service.
I am currently looking into RawHttpHandlers but since it is too early in the pipeline how do I get the authentication setup in the apphost config?
thanks in advance
Gjergji
You would have to use IAppHost.RawHttpHandlers because that's the only custom handler in ServiceStack's Request Pipeline that gets executed before the built-in static file handling is accessed.
But you should still be able to access the Users Session with the available extension methods, e.g:
this.RawHttpHandlers.Add(httpReq =>
{
var isStaticFileRequest = httpReq.PathInfo.StartsWith("/static");
if (isStaticFileRequest)
{
var session = httpReq.GetSession();
if (!session.HasRole("TheRole"))
return new ForbiddenHttpHandler();
}
return null;
});
This handler simply checks if it's a request for a static file, in this case the path info starts with /static, and if is checks the user session if they have the required role, if not it returns a Forbidden request, otherwise it returns null to tell ServiceStack to continue executing the request.
Note: if it's needed you can access any registered dependency from outside of ServiceStack with HostContext.Resolve, e.g:
var authRepo = HostContext.Resolve<IAuthRepository>();
I work on a new Symfony 2 project. I'm learning this framework at the same time. For the user management, I use the bundle FOSUserBundle.
My project works very well, I can login, register, logout and all other commands available.
The thing is that I want to make smartphone app which will use the API of my Symfony app. In the app, the user will have to sign in, or to sign up. Is it possible to use FOSUserBundle methods for API too?
I studied another bundle for making an API, it's FOSRestBundle.
If there are not solution, do you think that I will have to create my own users method like :
/api/login
/api/register
Then, inside this method, I redirect to FOSUserBundle methods? I'm just wondering what is the best, and the cleanest way to login, and register with FOSUserBundle from smartphone, so by using API
I have this problem too.
I found the best solution is this
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class YourController extends Controller{
//Other Methods..
public function loginAction(Request $request){
try{
$token = $this->get('security.authentication.manager')->authenticate(new UsernamePasswordToken('username', 'password', 'firewall'));
$this->get('security.context')->setToken($token);
}
catch(BadCredentialsException $e){
return new Response("Bad credentials", 403);
}
return new Response("success");
}
}
I used the FOSRestBundle.
This bundle is very powerful and simple to implement.
The documentation is pretty complete.
The github link of FOSRestBundle here
Hope that it helps
You need to check WSSE and how to integrate it to symfony.
Also check this post. And there is a bundle that implementing WSSE authentication. WSSE one of the best solutions for your app.