0

I have a problem adding an authentication feature to my spring boot application. I have implemented the session pattern as below.

AdminSession.java

@Component
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AdminSession {
private final String id = UUID.randomUUID().toString();
private Admin admin;

public String getId() {
    return id;
}

public Admin getAdmin() {
    return admin;
}

public void setAdmin(Admin admin) {
    this.admin = admin;
}
}

AdminController.java

@RequestMapping("/admin")
@CrossOrigin
@RestController
public class AdminController extends RestAbstractController<Admin, AdminService>{
@Autowired
private AdminService adminService;
@Autowired
private AdminSession adminSession;


@RequestMapping(value="/auth",method=RequestMethod.POST)
public ResponseEntity<Admin> auth(
@RequestParam("pseudo") String pseudo, 
@RequestParam("password") String password,
){
Admin a = this.adminService.auth(pseudo, password);
if(a instanceof Admin) {
this.adminSession.setAdmin(a);
System.out.println("[DEBUG] Login "+this.adminSession.getAdmin());
this.displaySessionInfo();
}else System.err.println("[ERROR] a is not Admin instance");
return new ResponseEntity<Admin>(a,HttpStatus.ACCEPTED);
}

public Admin add(@RequestBody Admin admin){
if(!this.adminService.exist(admin.getPseudo())){
return super.add(admin);
}else return new Admin();

}

@RequestMapping("/isAuth")
public Admin isAuth(){

this.displaySessionInfo();
return this.adminSession.getAdmin();

}

private void displaySessionInfo(){
System.out.println("[DEBUG] Session info : "+this.adminSession.getId()+" "+this.adminSession.getAdmin()+" "+this.adminSession.toString());
}


}

The problem is that when I try to connect to the Angular side, Spring saves the user correctly in the session. But when I try to access the URL '/ admin / isAuth' after logging in, the session is not the same.

console LOG

2017-05-03 19:08:52.258  INFO 756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 124 ms
# FIRST LOGIN
[DEBUG] Client connexion : 127.0.0.1 on /admin/auth
[DEBUG] Login root 
[DEBUG] Session info : 31e7a837-7b0e-4bcc-83a2-b5297a76d2e0 root fr.-----.session.AdminSession@6039cb34
# LOGIN SUCCESSFUL
# CHECK IS LOGIN
[DEBUG] Client connexion : 127.0.0.1 on /admin/isAuth
[DEBUG] Session info : f83ba190-0faa-480b-be1d-4b2745d4a168 null fr.-----.session.AdminSession@6052863f

Side Angular 2

Admin.service.ts

auth(pseudo:string,password:string):Observable<Admin>{
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded;' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.provider.getURL()+"/admin/auth","pseudo="+pseudo+"&password="+password,options)
.map(this.extractData);
}

Login.component.ts

submit(){
    this.process=true;
    this.adminService.auth(this.pseudo,this.password).subscribe(t=>{
      this.adminService.isAuth();
      this.process=false;
      this.adminService.isAuthentified = true;
      this.provider.tokenSession = t;
      this.adminService.isAuth().subscribe(t=>console.log("Test login"));
      this.router.navigate(['/']);
    },err=>console.error(err));
  }

Why I lost my http session ?

Thank for your help.

6
  • Did you test it with browser or other HTTP client first? Commented May 4, 2017 at 5:02
  • I test with the same http browser, the same onglet, different, ... Commented May 4, 2017 at 9:58
  • Can you show me how you inject this.adminService? Commented May 4, 2017 at 15:49
  • I have add the code juste below. Commented May 6, 2017 at 12:04
  • Everything looks normal. Need to start with elementary diagnosing. How about use http.get to send several test requests against a normal API. Then check how session behaves. Commented May 6, 2017 at 16:29

2 Answers 2

1

I have identified the problem. I'ts side Angular 2. For eatch request, the headers need 'withCredentials';

export class MyService {
  private httpGetOptions : RequestOptions = new RequestOptions({ withCredentials: true });

  getSomeone (): Observable<any> {
    return this.http.get(url,this.httpGetOptions);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

AdminService.java

@Service
public class AdminService extends RestAbstractService<Admin, AdminRepository>{

    @Autowired
    private AdminRepository adminRepository;

    public Admin auth(String pseudo, String password, AdminSession adminSession){
        Admin a = this.adminRepository.findAdminByPseudo(pseudo);
        if(a instanceof Admin)
            if(a.getPassword().equals(password)) {
                adminSession.setAdmin(a);
                a.setPassword(null);
                return a;
            }
            else return null;
        else if(pseudo.equals("root") & Admin.root.getPassword().equals(password))
            return Admin.root;
        else return null;
    }

    public boolean exist(String pseudo){
        return this.adminRepository.findAdminByPseudo(pseudo) instanceof Admin;
    }

    public boolean isAuth(AdminSession adminSession){
        return adminSession.getAdmin() instanceof Admin;
    }


    public void logout(AdminSession adminSession){
        adminSession.setAdmin(null);
    }
}

Admin.service.ts

@Injectable()
export class AdminService {
  isAuthentified:boolean;
  constructor(private provider :ProviderService, private http:Http) { }

  auth(pseudo:string,password:string):Observable<Admin>{
    let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded;' });
    let options = new RequestOptions({ headers: headers });
    return this.http.post(this.provider.getURL()+"/admin/auth","pseudo="+pseudo+"&password="+password,options)
      .map(this.extractData);
  }

  isAuth():Observable<boolean>{    
    let headers = new Headers({ 'Content-Type': 'application/json;', 'token': this.provider.tokenSession.token});
    let options = new RequestOptions({ headers: headers });
    return this.http.get(this.provider.getURL()+"/admin/isAuth",)
        .map(this.extractBoolean);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body;
  }

  private extractBoolean(res:Response){
    this.isAuthentified = res.text() === 'true';
    return this.isAuthentified;
  }


  private handleError (error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return Observable.throw(errMsg);
  }

}

In the "providerService" I have juste IP access to web service Spring.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.